了解派生类中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(); }
};
作者接着说
- 析构函数 (
~Vector_container()
) 覆盖基类析构函数 (~Container()
)。- 请注意,成员析构函数 (
~Vector()
) 由其类的析构函数 (~Vector_container()
) 隐式调用。
关于#1,为什么覆盖发生在不同名称的函数中?
关于 #2,成员析构函数是否由类的析构函数系统地调用是一个C++功能?
如果不添加析构函数,编译器会创建一个析构函数。在您的情况下,您有一个,因此编译器不会生成一个。
是的,成员和基类在调用类的析构函数后被销毁。从 cppreference.com:
对于用户定义的析构函数或隐式定义的析构函数,在 执行析构函数的主体,编译器调用析构函数 对于类的所有非静态非变量成员,按相反顺序排列 的声明,然后它调用所有直接的析构函数 非虚拟基类的构造顺序相反(在 轮调用其成员及其基类的析构函数, 等),然后,如果这个对象是大多数派生类,它调用 所有虚拟基础的析构函数。
1:析构函数是一个特殊的函数,名字在这里无关紧要。
2:是的,这是一个C++
功能。由于v
成员声明为Vector v
,容器的析构函数将自动调用其成员的析构函数Vector::~Vector
关于 #1,为什么覆盖发生在不同名称的函数中?
它不是覆盖。每个类都有其 on 析构函数,可能是用户定义的,也可能不是用户定义的。如果销毁对象,则在继承层次结构中按从下到上的顺序调用每个析构函数。
重要说明:如果您有虚拟基类并使用基指针销毁对象,则必须将析构函数标记为virtual
才能从下到上销毁,而不仅仅是基指针具有的类型。
关于 #2,成员析构函数是否由类的析构函数系统地调用是一个C++功能?
是的,析构函数从所有成员调用析构函数。
提示:如果成员是原始指针,则析构函数仅"销毁"指针,而不"销毁"它指向的元素。因此,您应该使用智能指针,或者注意删除您在其他地方创建的用户提供的析构函数中的所有对象。
为什么覆盖发生在不同名称的函数中?
因为它必须这样做。否则,对象销毁将不起作用。对象的基部也必须被破坏,所以这就是它的工作原理。
定义构造函数和析构函数的语法有点令人困惑,因为从技术上讲,这些东西没有名称(ref;dtor 没有特定的措辞,但同样适用于演绎推理)。您可以使用语法~<class name>
(ref)引用类的析构函数,但这本身不是函数名称。这听起来像是一个完全学术上的区别,嗯,确实如此......但它可能有助于使"不同的名称覆盖"不那么令人惊讶。
我也不会称之为"覆盖",这个术语通常用于描述虚函数的工作原理。Bjarne正在松散地使用它。
成员析构函数是否C++由类的析构函数系统地调用?
答案是肯定的。想象一下,如果销毁一个对象并没有破坏它封装的成员?您每次都必须自己手动完成。这违背了自动范围界定的目的。
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误