멤버함수에 대한 질문입니다...

bxhs의 이미지

#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가 불릴지...
고수분들의 가르침 바랍니다...
답은 알고 있지만, 돌아가는 원리가 궁금해서...

익명 사용자의 이미지

컴파일해서 실행해 보면 될 일을...

익명 사용자의 이미지

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()가 없습니다.

doldori의 이미지

코드를 정리해 보죠.

class B 
{ 
public: 
    virtual void hello();
    void show();
}; 

class C : public B 
{ 
public: 
    void hello();
}; 

C c_ob;
c_ob.show(); // (1)

이런 경우를 말씀하시나 봅니다. (1)에서 B::show()가 호출된다는 것은 당연합니다.
그리고 그 함수 내부에서 this의 정적 타입은 B*이지만 동적 타입은 C*이지요.
hello()가 가상 함수이므로 this->hello()에 의해 실제로 호출되는 함수는
C::hello()가 됩니다. 결국 매지님의 답변으로 다 설명이 될 수 있습니다.
참고로 이런 형태는 Template Method라고 부르는 일종의 디자인 패턴입니다.
show()는 인터페이스의 역할만 하고 실제 일은 hello()에서 하는 것이죠.
그리고 보통 hello()는 private 또는 protected로 만듭니다.
익명 사용자의 이미지

인덴트가 안된코드라 대충읽었더니 삽질했군요 ㅜ.ㅠ

B::show() 의 바디 안에서 동적/정적 바인딩을 보시면 됩니다. show는 B의 멤버이므로 this의 정적 타입은 B* 이죠. hello가 가상함수가 아니라면 정적 바인딩을 해서 B::hello()가 불리우고, hello가 가상함수라면 hello의 호출시 가상함수 테이블을 읽어야 하므로 동적 바인딩을 하게 되죠.

즉 이 경우엔 this 포인터에 대해서 생각하시면 됩니다. :D hello(); 라고 호출하는 대신 this->hello(); 라고 호출해주면 좀 더 이해가 빠르겠지요?

bxhs의 이미지

저도 그런 식으로 될거라고 예상은 했지만,
그런 식의 코드를 보지 못했던 터라...

template method 라...
역시 디자인패턴을 봐야하는군요..

두분다 감사합니다.

kihongss의 이미지

클래스에 가상함수가 포함될때 객체의 메모리 레이아웃에
대해 만든 자료가 있는데, 미약하지만 참고 바랍니다.

http://kihongss.cafe24.com/tt/down.php?attachname=182198.pdf

익명 사용자의 이미지

대강 문제는 해결된거 같은데 자료까지..감사합니다.
내용이 좋군요...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.