不能被继承的类

题目:用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不能被继承,这也就满足了题目的要求.
原文地址:https://www.cnblogs.com/wxdjss/p/5612222.html