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