1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <iostream> class Base { public: void Print() const { std::cout << "From Base" << std::endl; } }; class Derived : public Base { public: void Print() const { std::cout << "From Derived" << std::endl; } }; int main() { Base *b = new Derived(); b->Print(); // Base b->Base::Print(); // Base delete b; } | cs |
Base 클래스를 가리키는 포인터 b가 Base 클래스를 상속받는 Derived 클래스를 가리킬 수 있잖아.
19번째 줄 :
b->Print()는 Base 클래스의 Print()인지 Derived 클래스의 Print()인지 선택해야 하잖아.
출력은 "From Base"가 나옴.
20번째 줄 :
b->Base::Print()는 Base 클래스의 Print()라고 명시해줬으니까 당연히 "From Base"가 출력될거고.
이제부터는 내가 왜 "From Base"가 출력되는지 이해해보려고 나름 생각해본 방식임
Base 클래스를 가리키는 포인터 b(내가 코드에 p라고 적은줄 알고 그림에 p라고 적었는데 다시보니까 b임. 이해좀)가 Derived를 가리키잖아
근데 "내가 생각하기에(뇌피셜)" 메모리에 Derived 클래스는 위에 그림처럼
Derived 클래스에 상속받은 Base가 저장되는 부분, 그것을 제외한 Derived 클래스의 부분이라고 생각해봤거든
실제론 이렇게 되는지 모르겠음.
근데 만약 이게 맞다면 내가 생각한 것처럼 이해해도 되나 물어보고 싶음.
b는 Base를 가리키는 포인터지만 위 코드에서는 Derived를 가리킴.
그래서 b->print()를 적었을 때 Base의 Print()가 실행되는지, Derived의 Print()가 실행되는지는 생각해볼 필요가 없는 문제임
왜냐면 b는 Derived를 가리키고 있지만 위의 추측대로라면 Derived의 Base부분을 가리키고 있으니까.
그래서 "From Derived"가 출력되지 않고 "From Base"가 출력되는거임
이런식으로 생각해보는건 잘못된거임?
일단 메소드는 메모리에서 따로 저장되는거고 메모리에 derive를 만들면 base도 같이 만들어짐. print 출력은 c++ 에선 early 바인딩이 기본이라 포인터 타입이 결정한건데 vitual 키워드를 붙이면 late binding이 가능해짐.
"메모리에 derived를 만들면 base도 같이 만들어짐" : 그러면 메모리에 내가 그린 그림처럼 만들어지는거라 보면 됨? base하나 만들어지고 derived도 만들어지니까.
컴파일러가 결정하는 일이지 그건. 초창기 c++ 구현은 c로 구현했는데 니말대로 구조체안에 부모 구조체와 함수포인터를 담아서 구현함
아 컴파일러마다 다르구나
어렵다 어려워... - dc App