2012-09-21 3 views
1

나는 인터뷰에서이 질문을 받았다. 얼마나 많은 가상 테이블이 다음 프로그램을 생성하고 각 경우에 어떤 결과가 나오는가?가상 테이블에 대한 혼동

#include <iostream> 
using namespace std; 
class A 
{ 
virtual void func1() 
{ 
    cout << "0 " <<endl; 
} 

virtual void func2() 
{ 
    cout << "1 " <<endl; 
} 
}; 

class B:Public A 
{ 
    void func1() 
    { 
    cout << "2" <<endl; 
    } 
}; 

class C:public B 
{ 
virtual void func2() 
{ 
    cout << "3" <<endl; 
} 
} 

int main() 
{ 
A* objA; 

B objB ; 
C objC ; 

//case1: 
objA = &objB; 
objA->func1(); 
//case2: 
objA = &objC; 
objA->func2(); 
objA->func1(); 
return 0; 
} 

나는 클래스 B에서 혼란 스럽습니다. 클래스 B에 대한 vtable을 생성합니까? 이 함수는이 경우 호출됩니다. 누군가 나를 설명 할 수 있겠 어.

+0

프로그램이 컴파일되지 않습니다. 질문하는 질문은 학문적이다. 'A * objA; 또는'objA = * objB'와'objA = * objC'를 의미 했습니까? –

+0

우선, 위의 코드는 컴파일되지 않기 때문에 시작하는 출력이 없습니다. 그걸 먹여주지 마. 두 번째로 Dobb 박사의 [Multiple Inheritance Usefulful] (http://www.drdobbs.com/multiple-inheritance-considered-useful/184402074?pgno=1)에 훌륭한 기사가 있습니다.이 기사를 통해 상속 방법을 이해할 수 있습니다. 가상 메소드 테이블이 작동합니다. –

+0

기사 주셔서 감사합니다. 그것의 의사 코드. 기본적으로 vtable이 클래스 B에 대해 생성되는지 여부를 알고 싶습니까? – user1687824

답변

1

의견

// I'll pretend you have a #include <stdio.h> here 

class A 
{ 
virtual void func1() 
{ 
    print 0; // error!! I'll pretend this was puts("0"); 
} 

virtual void func2() 
{ 
    print1; // error!! I'll pretend this was puts("1"); 
} 
}; 

// there is a virtual table for class A. (for two virtual methods) 


class B:Public A 
{ 
    void func1() 
    { 
    print2; // error!! I'll pretend this was puts("2"); 
    } 
}; 

// there is a virtual table for class B. (for two virtual methods) 


class C:public B 
{ 
virtual void func2() 
{ 
    print 3; // error!! I'll pretend this was puts("3"); 
} 
} 

// there is a virtual table for class C. (for two virtual methods) 


int main() 
{ 
A objA; 
B* objB = new B(); 

C* objC = new C(); 

//case1: 
objA = &objB; // error!! left side of type A right side of type B** 
objA->func1(); // error!! operator -> on non pointer 

//case2: 
objA = &objC; // error!! left side of type A right side of type B** 
objA->func2(); // error!! operator -> on non pointer 
objA->func1(); // error!! operator -> on non pointer 
return 0; 
} 

// nothing is printed 
를 참조하십시오

OP 코드를 편집 했으므로 여기서 코드의 새 버전에 대한 대답입니다. 의견보기 :

#include <iostream> 
using namespace std; 
class A 
{ 
virtual void func1() 
{ 
    cout << "0 " <<endl; // it's ok, but is the space supposed to be there? 
} 

virtual void func2() 
{ 
    cout << "1 " <<endl; // it's ok, but is the space supposed to be there? 
} 
}; 
// there is a virtual table for class A. (for two virtual methods) 

class B:Public A // error!! I'll pretend Public was public (lowercase) 
{ 
    void func1() 
    { 
    cout << "2" <<endl; // it's ok, but here there's no space, is that correct? 
    } 
}; 
// there is a virtual table for class B. (for two virtual methods) 

class C:public B 
{ 
virtual void func2() 
{ 
    cout << "3" <<endl; // it's ok, but here there's no space, is that correct? 
} 
} 
// there is a virtual table for class C. (for two virtual methods) 

int main() 
{ 
A* objA; 

B objB ; 
C objC ; 

//case1: 
objA = &objB; 
objA->func1(); // outputs (to stdout) a '2' (two) and whatever a 
       // newline is on your system (could be '\r' or '\n' or both 
       // or in fact anything your platform defines a newline is) 
       // stdout is then flushed. 
//case2: 
objA = &objC; 
objA->func2(); // outputs (to stdout) a '3' (three) and whatever a 
       // newline is on your system (could be '\r' or '\n' or both 
       // or in fact anything your platform defines a newline is) 
       // stdout is then flushed. 

objA->func1(); // outputs (to stdout) a '2' (two) and whatever a 
       // newline is on your system (could be '\r' or '\n' or both 
       // or in fact anything your platform defines a newline is) 
       // stdout is then flushed. 
return 0; 
} 
// the output is '2' <newline> '3' <newline> '2' <newline> 
// where the actual character(s) for <newline> are platform dependent 
+0

코드를 지금 확인하십시오 – user1687824

+0

어쨌든, 지금 컴파일하는 것이 더 가깝습니다. 그러나 실제로 "컴파일"하면 "공용"과 "공용"이 동의어가 아닐 수도 있습니다. 편집 된 OP 코드에 – WhozCraig

+0

이 추가되었습니다. –

0

클래스 B의 인스턴스도 유형 A의 인스턴스입니다. 귀하의 클래스 B가 클래스 A의 생성자를 호출하고 B는 다음에서 FUNC1()를 오버라이드 (override)하지 않는 경우 B는 A.에서 가상 FUNC2()와 FUNC1에 대한 재정의를()가