2011-01-17 4 views
2

저는 C++을 배우고, 좋은 다형성 코드를 작성하고 혼란에 빠지기를 배우고 있습니다. 나는 "Generator"와 "Triggerable"이라는 두 개의 수퍼 클래스를 가진 Er_1Sine 클래스를 가지고있다.C++ : 다른 수퍼 클래스에 내 객체를 캐스팅하면 다른 포인터 주소가됩니다.

Er_1Sine은 다음과 같습니다

class Er_1Sine : public Generator, public Triggerable{ 

} 

I가 "ER1", 포인터 주소가 "ER1"의 주소와 일치를 설정하는 "발전기"포인터 (세대)를 작성하는 경우. 그러나 "트리거 가능"포인터의 주소 인 "trig"는 일치하지 않습니다. 무슨 일 이니? tr1이 er1과 gen이 동일한 객체를 가리키고 있지 않습니까?

er1 = new Er_1Sine(); 
Generator *gen = er1; 
Triggerable *trig = er1; 

printf("\n\n er1 as Er_1Sine: %p \n", er1); 
// outputs: "er1 as Er_1Sine: 0x4d28920" 

printf("er1 as Generator address: %p \n", gen); 
// outputs: "er1 as Generator address: 0x4d28920" 

printf("er1 as Triggerable address: %p \n\n", trig); 
// outputs: er1 as Triggerable address: 0x4d289f8 

답변

4

전체가이 아닌 올바른 경우, 복합 클래스는 서로 위에 겹쳐진 2 개의 개별 객체로 생각할 수 있습니다. 첫 번째가 최상위 (동일한 주소)이고 하나가 두 번째로 선언 된 주소 (따라서 다른 주소).

5

이 배수 상속 - 기본 클래스 하위 개체가 하위 인스턴스, 따라서 서로 다른 주소를 withing에 다른 오프셋에 있습니다. 암시 적 업 캐스팅 중에 포인터 값을 조정해야하는 것은 컴파일러 프런트 엔드입니다.

+0

이 바로 그 이유 때문에 포인터 값에 ==를 사용해서는 안됩니다. 아마도 자바와 같은 접근 방식을 취하고 동등한 함수 나 연산자를 작성하는 것이 좋습니다. –

+0

흠, 예, 아니오. 포인터를 비교하는 것은 내장 된 작업이므로 무시할 수는 없습니다. 인스턴스 비교에는 대부분 사용자 지정 연산자 집합이 필요합니다. 자바와 같은 것은 없습니다 ... :) –

+0

사실 포인터 ==에 대해 ==를 사용하는 것은 일반적으로 똑같은 객체를 가리키는 지 여부를 결정하는 데 완벽합니다. 표준을 올바르게 읽는다면 포인터는 비교할 때만 비교할 수 있기 때문입니다. 같은 유형 (가능한 유형 변환 이후)이므로이 경우 기본 클래스 포인터를 파생 클래스 1과 비교할 때 나중에 클래스가 암시 적으로 기본 클래스로 캐스트되므로 적절하게 조정되므로 두 파생 된 동일한 객체에서 시작됩니다. – Grizzly

1

하나의 포인터가 클래스의 Generator을 가리키고, 다른 포인터는 Triggerable 부분을 가리 킵니다. Generator와 Triggerable이 다르므로 같은 포인터가 될 수 없습니다.

1

다중 상속을 사용하면 다른 기본 클래스가 하위 개체 내에서 서로 다른 메모리 주소를 가질 수 있습니다.

관련 문제