面试:C++不可继承类

  面试中可能遇到让设计一个无法被继承的类。最简单的实现是将该类的构造函数设置为私有的,然后通过静态成员函数调用私有构造函数实例化对象,这样的类确实不可继承,但是使用起来非常不方便,必须使用静态成员实例化对象,而且对象存储在堆中,无法像一个普通的类一样的被使用。最佳的设计是结合私有构造函、友元、虚拟继承实现。

一、简单实现

 1 class Simple{
 2 private:
 3     Simple(){};
 4     ~Simple(){}
 5 private:
 6     static Simple* getInstance(){
 7         return new Simple();
 8     }
 9     static void deleteInstance(Simple* instance){
10         delete instance;
11     }
12 };

二、最佳实现

 1 template<typename T>
 2 class NoneInherit {
 3     friend T;
 4 private:
 5     NoneInherit() {
 6     }
 7     ~NoneInherit() {
 8     }
 9 };
10 
11 class Finalclass: virtual public NoneInherit<Finalclass> {
12 public:
13     Finalclass() {
14     }
15     ~Finalclass() {
16     }
17 };
18 
19 //class TestClass: public Finalclass {
20 //};

关键点:

  1. 模板类NoneInherit类,构造函数和析构函数都设置为私有,模板参数T设置为友元,这样友元类可以调用构造函数。例如FinalClass是NoneInherit的友元类,可以使用基类的私有构造函数和析构函数
  2. 虚拟继承virtual是最关键的点。如果继承时去掉virtual,FinalClass还是可以被继承的,那么为什么需要使用虚拟继承呢?因为在普通继承中,每个类只是初始化自己的直接的基类。那意味着,如果不使用virtual,TestClass继承Finalclass,由FinalClass再去调用NoneInherit类,由于FinalClass是NoneInHerit的基类,因此整个继承没有任何问题。由于FinalClass使用了虚拟继承,在创建TestClass的时候,TestClass类的构造函数要负责虚基类NoneInherit类的构造,而NoneInherit的构造函数是私有的,友元关系也无法继承,因此TestClass类没有访问的权限。
posted @ 2017-08-06 17:25  wxquare  阅读(950)  评论(0编辑  收藏  举报