C++防止类被继承

来源:互联网 发布:人工智能狂潮 编辑:程序博客网 时间:2024/05/18 10:03
学过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,那么代码就不会编译通过了。