멤버함수에 대한 질문입니다...
글쓴이: bxhs / 작성시간: 금, 2005/04/01 - 9:09오전
#include <stdio.h> #include <conio.h> #include <typeinfo> class B { int j; public: void hello() { printf("B's hello %u == %s \n" , this , typeid(this).name()); } void show() { printf("%s\n" , typeid(this).name()); hello(); } }; class C : public B { int k; public: void hello() { printf("C's hello %u == %s \n" , this , typeid(this).name()); } }; int main() { C c_ob; c_ob.show(); return 0; }
B클래스의 hello가 virtual로 돼있을때와
돼있지 않을때,
c_ob.show()안에서 어떤 hello가 불릴지...
고수분들의 가르침 바랍니다...
답은 알고 있지만, 돌아가는 원리가 궁금해서...
Forums:
컴파일해서 실행해 보면 될 일을...
컴파일해서 실행해 보면 될 일을...
c_ob가 C클래스에 대한 변수이기 때문에 C::show() 가 불리지요
c_ob가 C클래스에 대한 변수이기 때문에 C::show() 가 불리지요.
마찬가지로 C* pC = new C; B* pB = pC; 일때
pC->show() 는 C::show()가 불리고 pB->show()는 B::show()가 불리겠지요.
show가 virtual일때는 pB->show()가 C::show()를 호출할거고요.
virtual은 함수 호출을 동적으로 바인딩하라는 이야기입니다. 런타임에 해당 객체의 타입을 보고 호출할 함수를 결정하는 것이죠. virtual이 아니면 소스에 명시된 타입(C면 C, B면 B)을 가지고 정적 바인딩, 그러니까 컴파일 타임에 호출할 함수를 결정하는 것입니다. 컴파일 타임에 pB의 타입은 B(의 포인터)이므로 B::show(), pC의 타입은 C(의 포인터)이므로 C::show()가 불리지요.
결국 포인터나 레퍼런스 타입에 대한 함수호출 외엔 virtual이 영향을 미치지 않지요.
그렇게 간단한게 아닐텐데요..
답변은 감사합니다만..
정적 바인딩과 동적바인딩을 묻는게 아닙니다.
소스를 보면 그리 간단한 문제가 아님을 아실텐데요..
제 질문은 hello가 virtual일때를 묻는 것입니다.
그리고 C에는 show()가 없습니다.
코드를 정리해 보죠.[code:1]class B {
코드를 정리해 보죠.
이런 경우를 말씀하시나 봅니다. (1)에서 B::show()가 호출된다는 것은 당연합니다.
그리고 그 함수 내부에서 this의 정적 타입은 B*이지만 동적 타입은 C*이지요.
hello()가 가상 함수이므로 this->hello()에 의해 실제로 호출되는 함수는
C::hello()가 됩니다. 결국 매지님의 답변으로 다 설명이 될 수 있습니다.
참고로 이런 형태는 Template Method라고 부르는 일종의 디자인 패턴입니다.
show()는 인터페이스의 역할만 하고 실제 일은 hello()에서 하는 것이죠.
그리고 보통 hello()는 private 또는 protected로 만듭니다.
인덴트가 안된코드라 대충읽었더니 삽질했군요 ㅜ.ㅠB::show()
인덴트가 안된코드라 대충읽었더니 삽질했군요 ㅜ.ㅠ
B::show() 의 바디 안에서 동적/정적 바인딩을 보시면 됩니다. show는 B의 멤버이므로 this의 정적 타입은 B* 이죠. hello가 가상함수가 아니라면 정적 바인딩을 해서 B::hello()가 불리우고, hello가 가상함수라면 hello의 호출시 가상함수 테이블을 읽어야 하므로 동적 바인딩을 하게 되죠.
즉 이 경우엔 this 포인터에 대해서 생각하시면 됩니다. :D hello(); 라고 호출하는 대신 this->hello(); 라고 호출해주면 좀 더 이해가 빠르겠지요?
그렇군요
저도 그런 식으로 될거라고 예상은 했지만,
그런 식의 코드를 보지 못했던 터라...
template method 라...
역시 디자인패턴을 봐야하는군요..
두분다 감사합니다.
클래스에 가상함수가 포함될때 객체의 메모리 레이아웃에대해 만든 자료가
클래스에 가상함수가 포함될때 객체의 메모리 레이아웃에
대해 만든 자료가 있는데, 미약하지만 참고 바랍니다.
http://kihongss.cafe24.com/tt/down.php?attachname=182198.pdf
자료감사합니다.
대강 문제는 해결된거 같은데 자료까지..감사합니다.
내용이 좋군요...
댓글 달기