实现一个不可被继承的类有两种方式:
- 将基类的构造函数私有化
因为在C++中,当创建派生类的对象时,会首先调用基类的构造函数,然后再调用派生类的构造函数。因此,构造一个派生类对象会调用两个构造函数:一个是基类的,一个是派生类的。那么基类的构造函数被私有化后,派生类将无法访问基类的构造函数,从而导致编译错误,也就意味着我们实现了一个不可被继承的类。
示例如下:
class NoInheritable {
private:
NoInheritable() = default;
};
class TryToInheritable : public NoInheritable {};
int main () {
TryToInheritable tt;
}
编译错误:
noinheritablewithprivate.cpp: In function ‘int main()’:
noinheritablewithprivate.cpp:11:18: error: use of deleted function ‘TryToInherit::TryToInherit()’
11 | TryToInherit tt;
| ^~
noinheritablewithprivate.cpp:8:7: note: ‘TryToInherit::TryToInherit()’ is implicitly deleted because the default definition would be ill-formed:
8 | class TryToInherit : public NoInheritable {};
| ^~~~~~~~~~~~
noinheritablewithprivate.cpp:8:7: error: ‘NoInheritable::NoInheritable()’ is private within this context
noinheritablewithprivate.cpp:5:5: note: declared private here
5 | NoInheritable() = default;
| ^~~~~~~~~~~~~
但是这个设计方式限制了我们创建基类对象实例的途径,我们只能通过创建一个public静态成员的方式来创建类的实例。
示例如下:
class NoInheritable {
private:
NoInheritable() = default;
public:
static NoInheritable createInstance() {
return NoInheritable();
}
};
int main () {
NoInheritable ni = NoInheritable::createInstance();
}
- final关键字
C++11提供了一种防止继承发生的方法,即在类名后面跟一个关键字final。
class NoInheritableWithFinal final {};
class TryToInherit : public NoInheritableWithFinal{};
当我们写下这段代码时,会出现一段错误提示:
a 'final' class type cannot be used as a base class
这种方式操作简单,且不会出现其他的附作用,所以最为推荐。
当然,我们也可以通过final关键字限制析构函数的覆盖,来间接限制继承,这里不做赘诉。