Bootstrap

C++如何实现不可被继承的类

实现一个不可被继承的类有两种方式:

  1. 将基类的构造函数私有化

因为在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();
}
  1. final关键字

C++11提供了一种防止继承发生的方法,即在类名后面跟一个关键字final。

class NoInheritableWithFinal final {};

class TryToInherit : public NoInheritableWithFinal{};

当我们写下这段代码时,会出现一段错误提示:

a 'final' class type cannot be used as a base class

这种方式操作简单,且不会出现其他的附作用,所以最为推荐。

当然,我们也可以通过final关键字限制析构函数的覆盖,来间接限制继承,这里不做赘诉。

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;