题目:用C++设计一个不能被继承的类。
在C++中,子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的析构函数。要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那里继承的时候,必然会由于调用构造函数、析构函数而导致编译错误。同时,我们可以通过定义公有的静态函数来创造和释放类的实例。
class SealedClass
{
public:
static SealedClass* GetInstance()
{
return new SealedClass();
}
static void DeleteInstance(SealedClass* pInstance)
{
delete pInstance;
}
private:
SealedClass(){}
~SealedClass(){}
};
上面实现的类的确不能被继承,但它只能在堆上创建实例不能在栈上创建实例,那么如何实现一个类可以在堆上和栈上创建实例,同时不能被继承呢?
template<class T>
class MakeSealed
{
friend SealedClass1;
private:
MakeSealed(){}
~MakeSealed(){}
};
class SealedClass1 :virtual public MakeSealed<SealedClass1>
{
public:
SealedClass1(){}
~SealedClass1(){}
};
这个SealedClass1既可以在栈上创建实例,也可以在堆上创建实例。类MakeSealed的构造函数和析构函数都是私有的,但由于类SealedClass1是它的友元类型,因此在SealedClass1中调用MakeSealed的构造函数和析构函数都不会引起编译错误。
但当我们试图从SealedClass1中继承一个类并创建它的实例的时候,却不能通过编译。
由于类SealedClass1是从类MakeSealed虚继承过来的,在调用Try的构造函数的时候,会跳过SealedClass1而直接调用MakeSealed的构造函数。但Try不是MakeSealed的友元函数,因此不能调用它的私有构造函数。