不能被继承的类

Posted wxdjss

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不能被继承的类相关的知识,希望对你有一定的参考价值。

题目:用C++设计一个不能被继承的类.
 
常规的解法:把构造函数设为私有函数
我们通过定义共有的静态函数来创建和释放类的实例。
 class SealedClass1
{
  public:
   static SealedClass1* GetInstance()
   {return new SealedClass1();}
   static void DeleteInstance(SealedClass1* pInstance)
   {delete pInstance;}
   private:
   SealedClass1(){}
   ~SealedClass1(){}
};
 这个类是不能被继承,但总觉得它和普通的类型有些不一样,使用起来有点不方便.比如我们只能得到位于堆上的实例,而得不到位于栈上的实例。
 
新奇的解法:利用虚拟继承,能给面试官留下很好的印象
 template<typename T> class MakeSealed
 {
  friend T;
  private:
  MakeSealed() {}
  ~MakeSealed(){}
 }
 
class SealedClass2: virtual public MakeSealed<SealedClass2>
{
 public:
 SealedClass2(){}
 ~SealedClass2(){}
};
 
 这个SealedClass2使用起来和一般的类型没有多大差别,我们可以在栈上、也可以在堆上创建实例。尽管类MakeSealed<SealedClass2>的构造函数和析构函数都是私有的,
 但由于类SealedClass2是它的友元类型,因此在SealedClass2中调用MakeSealed<SealedClass2>的构造函数和析构函数都不会引起编译错误.
 但当我们试图从SealedClass2中继承一个类并创建它的实例的时候,却不能够通过编译。比如当我们从SealedClass2中继承出类型Try:
  class Try: public SealedClass2
 {
  public:
  Try(){}
  ~Try(){}
 };
 
 由于类SealedClass2是从类MakeSealed<SealedClass2>虚继承过来的,在调用Try的构造函数的时候,会跳过SealedClass2而直接调用MakeSealed<SealedClass2>的构造函数.
 非常遗憾的是Try不是MakeSealed<SealedClass2>的友元类型,因此不能调用它的私有构造函数.
 通过上面的分析,我们发现从SealedClass2继承的类,一旦实例化就会导致编译出错,因此SealedClass2不能被继承,这也就满足了题目的要求.

以上是关于不能被继承的类的主要内容,如果未能解决你的问题,请参考以下文章

C++实现一个不能被继承的类

[剑指offer]面试题48:不能被继承的类

用C++设计一个不能被继承的类(转)

JAVA,为啥final类不能被继承,如果定义为final的类该类里面成员变量不特殊说明则是final类还是非final

如何利用c++编写不能被继承但可以在类外定义对象的类

Final 用法