2012-11-18 5 views
1

한 가지에 대해 궁금합니다. 1 오버로드 된 멤버 함수가있는 클래스가 있습니다.함수 내부에 오버로드 된 버전을 호출하십시오.

class A{ 
    public: 
    class const_iterator{}; 
    class iterator : public const_iterator{}; 
    iterator find(const K &key); 
    const_iterator find(const K &key) const; 
}; 

Ad. iterator는 const_iterator를 상속하지만 아무 것도 추가하지 않습니다.

내가 원하는 것은 정상적인 호출 찾기 const 찾기입니다. 다음과 같은 것 :

typename A::iterator A::find(const K &key){ 
    const_iterator it(find(key)); 
    return (*(iterator*)&it); 
} 

비 const 찾기 ATM을 구현할 필요가 없습니다. 이런 식으로 할 수 있습니까? 왜냐하면 이제는 무한 루프에 빠지기 때문에 찾기 전에 "A ::"를 추가하면 아무것도 바뀌지 않기 때문입니다.

+0

가능한 복제본 : http://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func –

답변

2

일반적으로 불행히도이 해결책은 없습니다.

당신 단순히 thisA const*에 캐스팅에 의해 오버로드 find를 호출 - (하지만 결과이 잘못된 형식의 것 (const_iterator 오히려 iterator 이상) 및 일반적인 경우 이들 사이에 변환이되지 않을 수 있습니다 귀하의 (*(iterator*)&it) 귀하의 경우에는 작동하지 않습니다).

그러나 당신이 두 개의 클래스를 정의하기 때문에 물론, 특별한 경우에, 당신은 iterator에 적절한 생성자를 추가하여에게 이러한 변환을 정의 할 수 있습니다 :

class iterator : public const_iterator { 
    iterator(const_iterator const& other) { 
     // Construct … 
    } 
}; 

그런 다음 다시 쓸 수 있습니다 비 constfind 구현을 다음과 같이 또한

A::iterator A::find(const int &key){ 
    const_iterator it(const_cast<A const*>(this)->find(key)); 
    return static_cast<iterator>(it); 
} 

가 리턴 타입 typename 없음을주의. A::iterator은 종속 이름이 아니기 때문에 여기에 typename을 사용할 필요가 없습니다. (적어도 C++ 03에서는 허용되지 않습니다.)

+0

덕분에 많은 일을했는데, 템플릿이 있기 때문에 typename이 필요합니다. 그래서 포인터를 내려 놓는 간단한 동작을합니다. 변환을 정의 할 필요가 없었습니다. 어쩌면이 상속은 대부분 이름 만 바뀌고 isn이 아닙니다. 새로운 것을 구현하지 마십시오.) –

+0

@ MichałDębski 아니, 변환을 정의해야합니다.기본 클래스에서 파생 클래스로 자동 다운 캐스트가 없습니다. 포인터 캐스트가 금지되어 있으며 정의되지 않은 동작이 발생합니다. –

2
const_cast<const A*>(this)->find(key); 
+0

@Aardvark - 좋은 포인트. 'static_cast'를'const_cast'로 변경했습니다. 감사. –

+0

static_cast 또는 dynamic_cast 또는 일반 캐스트를 사용하지 않는 이유는 무엇입니까? 'const_cast <> '를 사용해야하는 이유는 무엇입니까? – 0x499602D2

+0

@David 우리는 객체의'const'-ness를 변경하기 때문에 더 이상 아무것도하지 않습니다. 게다가'dynamic_cast'는 상속 계층 내에서 캐스팅에만 적용되므로 (캐스팅이 성공할 것인지 확실하지 않은 경우에만 해당 결과 null 값을 처리하기 때문에) 여기에 완전히 잘못 될 것입니다. 여기의 경우. –