【问题标题】:Understanding behavior of the C++ destructor in a derived class理解派生类中 C++ 析构函数的行为
【发布时间】:2019-11-20 00:24:04
【问题描述】:

我正在阅读 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. 析构函数 (~Vector_container()) 覆盖基类析构函数 (~Container())。
  2. 请注意,成员析构函数 (~Vector()) 由其类的析构函数 (~Vector_container()) 隐式调用。

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

关于#2,类的析构函数系统地调用成员析构函数是C++的一个特性吗?

【问题讨论】:

    标签: c++ inheritance destructor


    【解决方案1】:

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

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

    对于用户定义或隐式定义的析构函数,在 析构函数的主体被执行,编译器调用析构函数 对于类的所有非静态非变体成员,以相反的顺序 的声明,然后它调用所有直接的析构函数 构造相反顺序的非虚拟基类(在 依次调用其成员及其基类的析构函数, 等),然后,如果这个对象是最派生类,它调用 所有虚基的析构函数。

    【讨论】:

      【解决方案2】:

      1:析构函数是一个特殊的函数,这里的名字无关紧要。

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

      【讨论】:

        【解决方案3】:

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

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

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

        关于#2,类的析构函数系统地调用成员析构函数是C++的一个特性吗?

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

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

        【讨论】:

          【解决方案4】:

          为什么在不同名称的函数中会出现覆盖?

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

          定义构造函数和析构函数的语法有点混乱,因为从技术上讲这些东西没有名字 (ref; dtor 没有具体的措辞,但同样适用于演绎推理)。您可以使用语法~<class name> (ref) 来引用类的析构函数,但这本身并不是函数名。这听起来像是完全学术上的区别,嗯,确实是……但它可能有助于使“不同的名称覆盖”不那么令人惊讶。

          我也不会称其为“覆盖”,这个术语通常用于描述虚函数的工作方式。 Bjarne 正在松散地使用它。

          类的析构函数系统地调用成员析构函数是 C++ 的特性吗?

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-04-16
            • 2014-08-08
            • 2020-09-29
            • 2011-02-14
            • 1970-01-01
            • 2015-07-18
            • 2017-07-12
            • 2013-03-30
            相关资源
            最近更新 更多