2012-09-21 107 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?在這種情況下哪個函數會被調用。有人可以解釋我。類B的

+0

程序不編譯;問的問題是學術問題。你是指'A * objA;'或'objA = * objB'和'objA = * objC'? –

+0

首先,上面的代碼甚至沒有編譯,所以沒有輸出。不要餵我們。其次,有一個精彩的文章中博士道博的,[多重繼承認爲是有用的(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

其相當接近現在編譯,無論如何,但如果你是真正* *編譯它,你可能會發現,「公共」和「公衆」是不是同義詞。 – WhozCraig

+0

到編輯OP代碼 –

0

實例是類型A的情況下也是如此。您的B級要求A類構造函數,如果B不從A然後覆蓋FUNC1()B具有A的虛擬FUNC2()和FUNC1的倍率()