了解派生 class 中 C++ 析构函数的行为

Understanding behavior of the C++ destructor in a derived class

我正在阅读 Stroustrup 的 C++ 编程书中的一段代码。

class Vector_container : public Container {
    Vector v;
public:    
    // Vector_container implements Container
    Vector_container(int s) : v(s) { } // Vector of s elements
    ~Vector_container() {}

    double& operator[](int i) { return v[i]; }
    int size() const { return v.size(); }    
};

作者接着说

  1. The destructor (~Vector_container()) overrides the base class destructor (~Container()).
  2. Note that the member destructor (~Vector()) is implicitly invoked by its class’s destructor (~Vector_container()).

关于#1,为什么覆盖发生在不同名称的函数中?

关于 #2,class 的析构函数系统地调用成员析构函数是否是 C++ 特性?

1:析构函数是一个特殊的函数,名字在这里无所谓

2:是的,这是一个 C++ 功能。由于 v 成员声明为 Vector v,容器的析构函数将自动调用其成员的析构函数 Vector::~Vector

如果您不添加析构函数,编译器将创建一个析构函数。在你的情况下你有一个,所以编译器不会生成一个。

是的,成员和基 classes 在 class 的析构函数被调用后被析构。来自 cppreference.com

For both user-defined or implicitly-defined destructors, after the body of the destructor is executed, the compiler calls the destructors for all non-static non-variant members of the class, in reverse order of declaration, then it calls the destructors of all direct non-virtual base classes in reverse order of construction (which in turn call the destructors of their members and their base classes, etc), and then, if this object is of most-derived class, it calls the destructors of all virtual bases.

Regarding #1, why does the overriding occur in functions of different names?

这不是覆盖。每个 class 都有自己的析构函数,可能是用户定义的,也可能不是。并且如果你销毁一个对象,每个析构函数在继承层次结构中按照从下到上的顺序被调用。

重要提示:如果你有虚基 class 并使用基指针销毁对象,你的析构函数必须标记为 virtual 以便从下到上进行析构,而不仅仅是基指针的类型。

Regarding #2, is it a C++ feature that member destructors are systematically invoked by the class's destructor?

是的,析构函数调用所有成员的析构函数。

提示:如果成员是原始指针,析构函数只"destruct"指针,而不是它指向的元素。因此,您应该使用智能指针或注意删除您自己在您在其他地方创建的用户提供的析构函数中的所有对象。

why does the overriding occur in functions of different names?

因为它必须。否则对象销毁将不起作用。对象的基础部分也必须被破坏,所以它是这样工作的。

定义构造函数和析构函数的语法有点混乱,因为技术上这些东西没有名字 (ref; no specific wording for the dtor but the same applies by deductive reasoning). You can refer to the destructor of a class with the syntax ~<class name> (ref) 但这本身并不是一个函数名。这可能听起来完全是学术上的区别,而且,嗯,它是......但它可能有助于使 "different name overriding" 不那么令人惊讶。

我也不会称其为 "overriding",该术语通常用于描述虚函数的工作方式。 Bjarne 正在随意使用它。

is it a C++ feature that member destructors are systematically invoked by the class's destructor?

当然可以。想象一下,如果销毁一个对象并没有销毁它封装的成员呢?您每次都必须自己手动完成。这违背了自动确定范围的目的。