회원 전환에 대한 포인터와 관련된 C++ 03 표준 초안에서 다음 단락을 발견했습니다. 부재 전환에회원 전환에 대한 포인터
는4.11/2 포인터
B 클래스 타입 인 "타입 CV T의 B의 부재 포인터 '유형의 r- 수치는 형태의 r- 수치로 변환 할 수"Cv T 유형의 D 멤버에 대한 포인터"는 D가 B의 파생 클래스 (10 절) 인 경우 B가 액세스 할 수 없거나 (11 절) 모호한 (10.2) 또는 D의 가상 (10.1) 기본 클래스 인 경우 이 변환을 필요로하는 프로그램은 부적절합니다. 변환 결과는 변환되기 전의 멤버에 대한 포인터와 동일한 멤버를 참조하지만 기본 클래스 멤버를 파생 클래스의 멤버 인 것처럼 참조합니다. 결과는 D의 B 인스턴스에있는 멤버를 참조합니다. 결과에 "cv T 유형의 D 멤버에 대한 포인터"유형이 있으므로 D 개체로 역 참조 할 수 있습니다. 결과는 B 구성원에 대한 포인터가 D의 B 하위 오브젝트로 역 참조 된 것과 같습니다. 널 (null) 구성원 포인터 값은 대상 유형의 널 (null) 구성원 포인터 값으로 변환됩니다 .52)
5.2.9/9 static_cast
"타입 CV1 (T)의 D의 부재 포인터 '유형의 r- 수치는"타입 CV2의 T의 B의 멤버에 대한 포인터 "형태의 r- 수치로 전환시킬 수있다 B는 "T 타입의 B의 멤버에 대한 포인터"에서 "T 타입의 D의 멤버에 대한 포인터"로의 유효한 표준 변환이 존재하고 (4.11), cv2가 동일한 cv 인 경우, D의 기본 클래스 (10 절) -자격 as 또는 cv-qualification보다 큰 cv-qualification) null 멤버 포인터 값 (4.11)은 대상 유형의 null 멤버 포인터 값으로 변환됩니다. 클래스 B가 원래 멤버를 포함하거나 원래 멤버를 포함하는 클래스의 기본 클래스 또는 파생 클래스 인 경우 멤버에 대한 결과 포인터는 원래 멤버를 가리 킵니다. 그렇지 않으면 형 변환의 결과가 정의되지 않습니다. [참고 : 클래스 B는 에 원래 멤버가 포함되어 있지 않아도 멤버에 대한 포인터가 역 참조되는 동적 유형에는 원래 멤버가 있어야합니다. 5.5 참조. ]
여기 내 질문이 있습니다. 5.2.9/9에서 말한 것처럼 4.11/2에 기술 된 유효한 변환이 존재하면 D의 멤버에 대한 포인터를 B의 멤버에 대한 포인터로 변환 할 수 있습니다. 이것은 B에서 상속받지 않은 D의 멤버 'm'이있는 경우 멤버 'm'에 대한 포인터를 B 멤버에 대한 포인터 유형으로 형변환 할 수 없다는 것을 의미합니까?
5.2.9/9의 노트에서class Base { };
class Derived : public Base
{
int a;
};
typedef int Base::* BaseMemPtr;
BaseMemPtr pa = static_cast<BaseMemPtr>(&Derived::a); // invalid, as per 5.2.9/9 ?
, 그것은 또한 말한다 클래스 B는 원래 회원, 회원에 대한 포인터가 원래 멤버를 포함해야합니다 역 참조되는 객체의 동적 유형을 포함 할 필요가 있지만, .
단락의 문구와 혼동합니다. 위의 코드가 유효합니까?
사이트를 검색 한 결과 비슷한 질문 인 c++ inheritance and member function pointers가 있는데, 포인터에서 기본 클래스 멤버로의 변환에서 파생 클래스 멤버에 대한 포인터로 변환하는 경우에만 해당됩니다.
데이터 멤버 값에 대한 포인터를 멤버 함수 변수에 대한 포인터에 할당합니다. 그렇지 않으면, 옙, "캐스트 결과가 정의되지 않았습니다." – Potatoswatter
고마워, 고쳤어. – ashen