基类中受保护的非虚拟析构函数

usu*_* me 4 c++ protected virtual-destructor

我试图了解虚拟析构函数.以下是此页面的复制粘贴何时使用虚拟析构函数?

在这里,您会注意到我没有声明Base的析构函数是虚拟的.现在,我们来看看以下代码段:

Base *b = new Derived(); // use b 
delete b; // Here's the problem!
Run Code Online (Sandbox Code Playgroud)

[...]如果要防止通过基类指针删除实例,可以使基类析构函数受保护且非虚拟; 通过这样做,编译器将不允许您在基类指针上调用delete.

我不明白为什么通过拥有受保护的非虚基类析构函数来防止删除.编译器是否认为我们试图delete从基类对象调用?什么是protected有,这样做?

Ben*_*igt 11

C++标准有这样的说法delete(第5.3.5p10节):

对释放函数和析构函数(12.4,12.5)进行访问和模糊控制.

因此,只有能够访问析构函数的代码才能使用delete.由于析构函数是protected,这意味着没有人可以调用delete类型的指针Base*.只有子类可以使用析构函数(唯一的东西是子类自己的析构函数,作为子对象销毁过程的一部分).

当然,子类应该创建自己的析构函数public,允许您通过子类类型删除对象(假设它是正确的实际类型).

注意:实际上,其他成员Base可以delete (Base*)p;访问,因为他们可以访问.但C++假定使用此构造的人不会这样做--C++访问控制仅为类外的代码提供指导.


Igo*_*nik 6

delete b;有效地执行b->~Base(); deallocate(b);.第一部分 - 调用析构函数 - 如果析构函数不可访问将无法编译(与调用任何其他不可访问的方法失败的方式相同).

  • @BenVoigt:Java 有静态方法。那些是“派遣”的吗?我怀疑,即使“方法”一词曾经有一个严格的定义,就像你坚持的那样,口语使用已经明显偏离了这样的定义,无论好坏。 (2认同)