C++中如何防止一个类被继承?

2017-04-16 18:44 阅读 320 次 评论 0 条

在C#中定义了关键字sealed,被sealed修饰的类是不能被继承的。同样在Java中也有关键字final表示一个类型不能被继承。然而在C++中却没有类似于sealed和final的关键字,因此就只能模拟实现它。这道题出自剑指offer,备受青睐的一道面试题。

防止被继承的思想

在C++中,子类的构造函数会自动调用父类的构造函数,子类的析构函数也会自动调用父类的析构函数。说到这你可能明白了,要想一个类不能被继承,我们只要把它的构造函数和析构函数都定义为私有函数,那么当一个类试图去继承的时候,必然会由于调用构造函数和析构函数而导致编译错误。

下面就为大家介绍两种方法来防止一个类被继承。

将构造函数设为私有函数

我们将构造函数和析构函数定义为私有函数,那么我们如何才能得到该类型的实例呢?我们可以通过定义公有的静态函数来创建和释放类的实例。

发现连编译都通过不了,说明这个类是不能被继承的,但是这样的类让人总感觉使用起来不方便,比如我们只能得到位于堆上的实例,而得不到栈上的实例。

使用虚拟继承

使用虚拟继承就会弥补上述的缺点,我们可以在堆上或栈上创建实例,当然我们不仅将派生类声明为基类的友元,而且还引入了虚拟继承的特性,具体我们先看代码:

现在编译运行肯定也不会出错了。尽管MakeSealed<SealedClass>的构造函数与习惯函数都是私有的,但由于类SealedClass是它的友元类型,因此在SealedClass中调用MakeSealed<SealedClass>的构造函数和析构函数就不会出错。

但是如果我们从派生类中继承一个类并创建它的实例时,却不能编译通过,比如我们在派生类SealedClass中继承出类型Code:

因为SealedClass是从类MakeSealed<Sealed>中虚拟继承的,在调用Code的构造函数时,会跳过SealedClass而直接调用MakeSealed的构造函数,但是Code不是类MakeSealed的友元函数,也就意味着不能访问人家的私有函数。

现在我们将虚拟继承的代码在linux的G++环境下跑一下看会发生什么:

g++环境下错误还是很多的,说明该程序的可移植性并不好,这是因为gcc和g++编译器中还不支持模板参数类型作为友元函数。

版权声明:本文著作权归原作者所有,欢迎分享本文,谢谢支持!
转载请注明:C++中如何防止一个类被继承? | 术与道的分享
分类:编程素养 标签:, ,
1024do.com导航_术与道导航平台

发表评论


表情