用C++实现一个不能被继承的类(例1)ios
#include <iostream> using namespace std; template <typename T> class Base{ friend T; private: Base(){ cout << "base" << endl; } ~Base(){} }; class B:virtual public Base<B>{ //必定注意 必须是虚继承 public: B(){ cout << "B" << endl; } }; class C:public B{ public: C(){} //继承时报错,没法经过编译 }; int main(){ B b; //B类没法被继承 //C c; return 0; }
类Base的构造函数和析构函数由于是私有的,只有Base类的友元能够访问,B类在继承时将模板的参数设置为了B类,因此构造B类对象时们能够直接访问父类(Base)的构造函数。c++
参见 c++Primer 4th 第17.3.7节 特殊的初始化语义面试
一般每一个类只初始化本身的直接基类,可是在虚继承的时候这个状况发生了变化,可能致使虚基类被屡次初始化,这显然不是咱们想要的。(例2: AA,AB都是类A的派生类,而后类C又继承自AA和AB,若是按以前的方法会致使C里面A被初始化两次,也会存在两份数据)函数
为了解决重复初始化的问题,从具备虚基类的类继承的类在初始化时进行了特殊处理,在虚派生中,由最低层次的派生类的构造函数初始化虚基类。在咱们上面的例1中就是由C的构造函数控制如何进行虚基类的初始化。spa
回到例1,由于B是Base的友元,因此B对象能够正常建立,但因为B使用了虚继承,因此若是要建立C对象,那么C类的构造函数就要负责虚基类(Base)的构造,可是Base的构造函数是私有的,C没有访问的权限(ps:友元关系不能被继承的),因此例1中的C类在编译时就会报错。这样B类就不能被继承了。code
----------------------------------------------------对象
吐槽一下:面试中被问到这个问题,虽然答出了实现方法,可是原理没回答上,因而回来以后查了一下继承
你们都说这属于“奇技淫巧”,哎,面试官就爱问这些 我也很无语啊
io