NeuroWhAI의 잡블로그

[C++] 다중 상속시 인스턴스 주소를 얻을 때 주의할 점 본문

개발 및 공부/언어

[C++] 다중 상속시 인스턴스 주소를 얻을 때 주의할 점

NeuroWhAI 2018. 9. 30. 16:00


포인터의 타입이 달라도 같은 인스턴스를 가리키고 있다면 주소는 다 같을 줄 알았는데 아니더라고요.

#include <iostream>

class Mother
{
public:
    virtual void foo1() { }
    int a;
};

class Father
{
public:
    virtual void foo2() { }
    int b;
};

class Child : public Mother, public Father
{
public:
    int c;
};

int main()
{
    Child c;
    Mother* m = &c;
    Father* f = &c;
    
    if ((void*)&c == (void*)m)
    {
        std::cout << "I like Mother." << std::endl;
    }
    
    if ((void*)&c == (void*)f)
    {
        std::cout << "I like Father." << std::endl;
    }
    
    return 0;
}

실행 결과는 아마 컴파일러마다 다를 듯하지만 보통 "I like Mother."만 출력이 되네요.

(상속 순서랑 보통 관련이 있는 듯)

결과 : https://ideone.com/M9VnX6


허허...

부모 둘 다 가상 메소드를 가지고 있는 다중상속이 아닐때는 이런 문제가 없는 듯 합니다만

아무튼 같은 인스턴스를 가리키고 있음에도 주소값이 다를 수 있다는걸 이제야 알았네요.

큰일인데? ㅎ...


관련 문서 : https://shaharmike.com/cpp/vtable-part2


위 문서에 따르면 원인은 인스턴스가 2개 이상의 vptr을 가지게 됨으로서 특정 부모 포인터 타입으로 캐스팅 되었을때 this가 올바른 vptr를 가리키게 하기 위해서 이렇게 된다고 하네요.


아 추가적으로 위 코드에서 (void*) 캐스팅을 빼면 Mother, Father 둘 다 출력됩니다.

타입 정보만 유지된다면 알아서 변환이 되는 듯 하네요.


'개발 및 공부 > 언어' 카테고리의 다른 글

[C++] Memory order  (0) 2018.10.16
[Kotlin] object  (0) 2018.10.07
[Kotlin] Data class, Inner class  (0) 2018.09.29
[Kotlin] 프로퍼티  (0) 2018.09.22
[C++] Structured binding 설명  (0) 2018.09.20


Comments