上篇文章記錄了C++類內虛函數的實現原理和經過子類調用父類方法的問題。此次繼續記錄些面試遇到的問題,大部分問題比較基礎,可是都是我這個畢業狗最近遇到的,但願記錄下來之後會有用。 ios
3. 繼承與訪問權限 面試
父類\繼承 | public | protected | private |
public | public | protected | private |
protected | protected | protected | private |
private | private | private | private |
所謂都多重繼承問題就是在下面這段代碼中若是使用D調用test()方法,會提示error C2385: 'D::test' is ambiguous這個錯誤。緣由就是由於類D同時繼承了類B和類C,而類B和類C又同時繼承了類A,因此類A的方法test()產生了二義性的問題。 函數
class A { public : void test(){ std::cout<<"This is A's test()"<<std::endl;}; }; class B : public A {}; class C : public A {}; class D : public B, public C {};
而咱們能夠經過修改代碼,是類B和類C虛繼承類A來解決這個問題。 spa
class A { public : void test(){ std::cout<<"This is A's test()"<<std::endl;}; }; class B : virtual public A {}; class C : virtual public A {}; class D : public B, public C {};
這裏就須要來解釋下虛繼承的概念。 code
虛繼承(Virtual Inheritance),解決從不一樣途徑繼承來的同名的數據成員在內存中有不一樣的拷貝形成數據不一致問題,將共同基類設置爲虛基類。這時從不一樣的路徑繼承過來的同名數據成員在內存中就只有一個拷貝,同一個函數名也只有一個映射。 繼承
也就是說,使用虛繼承以後類D內只會有一個test()方法的拷貝。在看一下完整的代碼。 內存
#include <iostream> using namespace std; class A { public : A() { std::cout<<"This is A"<<std::endl;} void test(){ std::cout<<"This is A's test()"<<std::endl;}; int aa; }; class B : virtual public A { public: B() {aa = 2; std::cout<<"This is B"<<std::endl;}; }; class C : virtual public A { public: C() {aa = 3; std::cout<<"This is C"<<std::endl;}; }; class D : public B, public C {}; int main() { D d; d.A::test(); d.B::test(); d.C::test(); d.test(); std::cout<<d.aa<<std::endl; return 0; }
這段程序運行結果是: ci
This is A This is B This is C This is A's test() This is A's test() This is A's test() This is A's test() 3
所以能夠肯定這四種調用test()的方法都是可行的。可是當類B和類C沒有虛繼承類A時只有d.B::test()和d.C::test()時可用的。 it