上篇文章记录了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