2010-01-31 7 views
3

모두. 왜 벨로우즈 코드가 작동하려면 캐스트가 필요한지 알 수 없습니다. 누군가 그것을 설명 할 수 있습니까? Base이 (공변) 허용한다면, 당신은 다음 노 아니오없는이, 할 수 있기 때문에구성원 기본 클래스에 대한 포인터

class Base { 
}; 

class Derived : public Base { 
}; 

class Class { 
public: 
    Derived member; 
}; 

... 

Derived obj; 
Base *ptrObj = &obj; // ok, no cast needed 

Derived Class::* ptr = &Class::member; // ok 
Base Class::* ptr = &Class::member; // wrong, need cast, why? 
+0

이전에이 구문을 본 적이 없습니다. 어떤 사람이 나를 의미하는 것에 연결 시키면 이러한 것들을 검색하는 것은 불가능합니다. –

+2

이것은 포인터를 가리키는 포인터입니다. :-) –

답변

4

: 동시에

Base Class::* ptr = &Class::member; 
Class obj; 
obj.*ptr = Base(); // <-- assigned a Base into a Derived field?! 

을, 포인터 - 투 - 회원 중 contravariant 수 없습니다 그렇지 않으면 당신은 또한 노 아니오없는이 작업을 수행 할 수 있기 때문에, :

struct Class2 { 
    Base member; 
}; 

Derived Class2::* ptr2 = &Class2::member; 
Class2 obj2; 
obj2.member = Base(); 
Derived& d = obj2.*ptr2; // <-- assigned a Base into a Derived 

그래서, 포인터 --회원이 아니 공변도 contravariant하지만, 불변 : 유형이 정확히 일치해야합니다.

+0

이것은별로 설득력이 없습니다. 기본 포인터를 사용하여 파생 된에 기본을 할당 할 수 있습니다 (그렇지 않으면 기본 클래스 포인터에 대한 파생 클래스 포인터를 사용할 수 없음). 따라서 멤버 포인터를 사용하지 않는 이유는 무엇입니까? – interjay

0

좋아, 내가 당신의 포인트 크리스있어,하지만 첫 번째 예제는 일반 포인터에 대한 작동합니다. 왜 멤버 포인터에 대해서도 작동하지 않아야합니까? 아래 코드를 참조하십시오.

Derived obj; 
Base *ptr = &obj; 

*ptr = Base(); // it's weird, but ok 

두 번째 예제는 캐스팅없이 다운 캐스팅이 허용되지 않으므로 일반 포인터에도 작동하지 않습니다. 그래서 나는 그것이 설명이되어야한다고 생각하지 않습니다.

+1

"답변 추가"기능으로 답변에 의견을 추가하거나 답변을 게시하지 않고 질문을 편집하십시오. –

+0

첫 번째 예와 같지 않습니다. 'Base'가'Derived'가 아니기 때문에 일반 포인터를 사용하여'Derived * obj = Base()'라고 말할 수 없습니다. 'Derived '에'base'에없는'someInt'가 있다면 어떻게 될까요? 그렇다면'obj'가'Base' 일 때'obj-> someInt'를 할 때 어떤 일이 일어나야합니까? –

관련 문제