在 C++ 中,为什么派生类不能不使用范围解析运算符而直接显式地调用其基类的析构函数?
我听说在C++中,所有的析构函数都会被编译器处理成“destructor”,也就是说基类和派生类的析构函数同名,从而导致重定义(隐藏)。
这是正确的吗?
#include <iostream>
struct base {
base() { std::cout << "base default \n"; }
~base() { std::cout << "~base \n"; }
};
struct derived : base {
derived() { std::cout << "derived default \n"; }
~derived()
{
//~base();No
base::~base();
std::cout << "~derived \n";
}
};
我知道在实践中几乎没有必要这样做,我只是想了解原理......
阅读错误信息。它相当有用:
继承并不是那么重要,你会得到同样的错误:
如果定义
base
了operator~
析构函数,那么该行代码会创建一个临时base
对象并调用该运算符。我想没人会真正在意如何解决歧义,因为手动调用析构函数的情况非常少见。另请注意(摘自cppreference):据我所知,唯一可以显式调用析构函数的情况是使用
placement-new
,这相当高级,并非日常工具。即使在那种情况下,您也应该调用对象的正确析构函数,而不是只调用某个基类的析构函数。此外,就像创建对象不仅仅是调用构造函数一样,仅仅调用析构函数也无法正确地销毁对象。如果手动调用析构函数,则还必须手动释放内存。
换句话说,如果您想手动完成所有操作,那么您必须正确地完成,否则就根本不要做。
要调用基类析构函数,请编写:
如果您在代码中执行此操作,则创建
derived
并销毁它将调用未定义的行为,因为基类析构函数已被调用,因此您不必手动执行此操作。