C++中禁止类被继承的方法

来源:互联网 发布:国泰安股票收益率数据 编辑:程序博客网 时间:2024/06/06 00:50
 

学过C++,看过一些C++书籍的人一般都知道怎么防止一个类被构造初始化,被赋值等等,它们的思想都一样,就是把相应的操作放到private区域中。现在,给大家介绍一种防止一个类被继承的方法,很巧妙~~
要防止一个类被继承,我们的目标就是如果这个类被继承,那么编译的时候就会出错,要是现这个目标,我们必须利用语言的一些特性,使得继承的类在编译时 C++需要为它生成一些代码,但是由于其它一些原因而生成不了(回想一下防止类被构造,被赋值的思想也是这样)。现在假设不能被继承的类为 NotABase,我们可以让NotABase成为一个不能被显式构造(默认构造函数为private)的类Uninheritable的友元,并且让 NotABase继承自Uninheritable,这样NotABase的构造函数能够调用Uninheritable的私有构造函数了,但是继承自 NotABase的类确不能访问Uninheritable的私有构造函数,因此理论上NotABase不能被继承。
说的有点绕了… 先看段代码:

class Uninheritable {
friend class NotABase;
private:
Uninheritable(void) {}
};

class NotABase: public Uninheritable {
// WHATEVER
};

class NotADerived: public NotABase {
// WHATEVER ELSE
};

现在仔细想想,你认为上面这段代码能实现NotABase不能被继承吗?其实上面的解释有一步有问题,如果NotADerived继承自 NotABase,那么NotADerived只会调用NotABase的构造函数,再由NotABase去调用Uninheritable的构造函数,因此NotADerived没有直接访问Uninheritable的私有构造函数!代码可以编译通过。
那么,怎么办呢?我们差目标就只有一步之遥了,就是需要让NotADerived访问Uninheritable的私有构造函数。也就是让继承体系中最底层的类调用 base class的构造函数,说到这里,你想到什么没?对!就是virtual base,为了实现virtual base的功能(多个类继承自同一个基类时,共享同一个基类,为了防止基类被多次初始化,基类的初始化任务必须由继承体系中最底层的类完成),ok~这个正是我们需要的:

class Uninheritable {
friend class NotABase;
private:
Uninheritable(void) {}
};

class NotABase: public virtual Uninheritable {
// WHATEVER
};

class NotADerived: public NotABase {
// WHATEVER ELSE
};

这样,如果有任何类继承自NotABase,那么代码就不会编译通过了。

下面,我们将代码泛化以便支持任意类不可被继承。

template <class OnlyFriend> 
class Uninheritable {
friend class OnlyFriend;
Uninheritable(void) {}
};

class NotABase : virtual public Uninheritable<NotABase> {
// WHATEVER
};

class NotADerived: public NotABase {
// THIS CLASS GENERATES A COMPILER ERROR
};

class AnotherUninheritable : virtual public Uninheritable<AnotherUninheritable> {
// WHATEVER
};

 

经过试验后, 发现还是不能在编译阶段报错。

另外一个简单的方法是只把父类的构造函数声明为私有的就可以了。效果和上面的代码一样。

原创粉丝点击