好点子网站建设,太原网站建设杰迅,标志设计欣赏网站,免费公司网站主页模板面试题48#xff1a;不能被继承的类 题目#xff1a;用C设计一个不能被继承的类。
❖ 常规的解法#xff1a;把构造函数设为私有函数
很多人都能够想到#xff0c;在 C中子类的构造函数会自动调用父类的构造函数#xff0c;子类的析构函数也会自动调用父类的析构函数。 …面试题48不能被继承的类 题目用C设计一个不能被继承的类。
❖ 常规的解法把构造函数设为私有函数
很多人都能够想到在 C中子类的构造函数会自动调用父类的构造函数子类的析构函数也会自动调用父类的析构函数。 要想一个类不能被继承我们只要把它的构造函数和析构函数都定义为私有函数。那么当一个类试图从它那继承的时候必然会由于调用构造函数、析构函数而导致编译错误。 可是这个类型的构造函数和析构函数都是私有函数我们怎样才能得到该类型的实例呢我们可以通过定义公有的静态函数来创建和释放类的实例。基于这个思路我们可以写出如下代码
class SealedClass1
{
public:static SealedClass1 *GetInstance(){return new SealedClass1();}static void DeleteInstance(SealedClass1 *pInstance){delete pInstance;}
private:SealedClass1() {};~SealedClass1() {};
};这个类是不能被继承但总觉得它和普通的类型有些不一样使用起来有点不方便。比如我们只能得到位于堆上的实例而得不到位于栈上的实例。
❖ 新奇的解法利用虚拟继承能给面试官留下很好的印象
能不能实现一个与一般的类型相比除了不能被继承之外其他用法都一样的类型呢办法还是有的不过需要一定的技巧。请看如下代码
templatetypename T
class MakeSealed
{friend T;
private:MakeSealed() {};~MakeSealed() {};
};class SealedClass2 :virtual public MakeSealedSealedClass2
{
public:SealedClass2() {};~SealedClass2() {};
};这个SealedClass2使用起来和一般的类型没有区别我们可以在栈上、也可以在堆上创建实例。尽管类MakeSealed的构造函数和析构函数都是私有的但由于类 SealedClass2 是它的友元类型因此在SealedClass2中调用MakeSealed的构造函数和析构函数都不会引起编译错误。
但当我们试图从SealedClass2中继承一个类并创建它的实例的时候却不能通过编译。
比如我们从SealedClass2中继承出类型Try
class Try :public SealedClass2
{
public:Try() {};~Try() {};
};
由于类SealedClass2是从类MakeSealed虚继承过来的在调用 Try 的构造函数的时候会跳过 SealedClass2 而直接调用MakeSealed的构造函数。非常遗憾的是Try 不是MakeSealed的友元类型因此不能调用它的私有构造函数。 通过上面的分析我们发现从SealedClass2继承的类一旦实例化就会导致编译出错因此SealedClass2不能被继承这也就满足了题目的要求。
本题考点 ● 考查发散思维能力。当要求设计一个不能被继承的类时应聘者要马上从把构造函数定义为私有函数出发去寻找解题方法。 ● 考查对C多个概念的理解比如构造函数、模板、友元等。