분산이 뒤로 있습니다.
반환 형식은 암시 적으로 기본 형식 (반 변형)으로 변환됩니다. 그러나 매개 변수는 암시 적으로 파생 된 유형 (공분산)으로 변환되며, 포인터가있는 멤버의 클래스 유형은 매개 변수으로 작동합니다. 이를 확인하기 위해 Liskov 대체 원리를 적용 해 봅시다 : Base*
계약은 : *
연산자를 사용할 때 "나는 당신에게 기지를 줄"입니다. Derived*
의 계약은 "나는 당신에게 파생물을 주겠다.
분명히 Derived*
이 Base*
대신 사용될 수 있습니다. 따라서 Derived*
에서 Base*
으로의 암시 적 변환이 있습니다.
그러나 회원 포인터에 대한 계약을 고려하십시오.
int Base::*
의 계약은 "나에게 자료를주고 내가 INT에게 당신을 줄 것이다"(A 파생은 기본, 그래서 사람들이 너무 좋아하다) 을 int Derived::*
의 계약은 "나에게 줘 파생 및 나는 "int를 당신을 다시 줄 것이다 (그러나하지 않습니다 오래된 Base
, 그것은 Derived
해야합니다)
당신이 Derived
아닌 Base
을 가지고 상상해보십시오. int Base::*
을 역 참조 할 때 제대로 작동하지만 int Derived*
과 함께 사용할 수는 없습니다.
그러나
Derived
사용자는
int Base::*
과
int Derived::*
을 모두 역 참조 할 수 있습니다. 따라서
int Derived::*
아아에 int Base::*
에서 암시 적 변환이, 나는 당신이 말한과 회원이 속한 유형을 분석 무엇을했다.
LSP는 여전히 작동합니다. 그리고 적어도 유형 안전에 따라 전환이 합법적이어야한다는 것에 동의합니다.계약서는 "내게 Foo
을 줘. 나는 너에게 Derived
"을 줄 것이다. 분명히 암시 적 변환으로 구성하여 Foo
에서 Base
까지 얻을 수있다. 그래서 안전합니다. DeadMG는 기본 하위 객체의 관계 위치, 특히 가상 상속의 잠재적 인 복잡성을 지적하는 올바른 방법 일 것입니다. 그러나 멤버 간 포인터는 참조 연산자의 LHS에서 이러한 문제를 처리하므로 결과도 마찬가지입니다.
최종 답변은 아마도 표준에서 변환이 합법적 일 것을 요구하지 않는다는 것입니다.
"기본 *에서 파생 * 로의 변환은 일반적으로 허용됩니다." 나는 당신이 이것을 뒤로 가지고 있다고 생각합니다. –
잘 잡으세요. 결정된. – Chris
http://stackoverflow.com/questions/4295117/pointer-to-member-conversion을 참조하십시오. – icecrime