为什么类构造函数为其成员生成析构函数?
Why class constructor generates destructors for its members?
让我们从热身开始。
我创建了一个类模板,如果不激活编译器,其析构函数就无法实例化static_assert
:
文件: M.hpp
template <typename T>
struct M
{
M(){}
~M()
{
static_assert(sizeof(T) == 0, "no type can pass this");
}
};
接下来,我以两种不同的方式使用这个类:在堆上分配它并在堆栈上分配它:
文件主.cpp
#include "M.hpp"
int main()
{
M<int> *pmi = new M<int>(); // does compile
M<int> mi; // doen't compile
}
将其分配给堆M<int> *pmi = new M<int>();
工作。之所以如此,因为我们只使用构造函数,不需要析构函数。类模板隐式实例化的规则说:
。除非在程序中使用该成员,否则不会实例化...
在堆栈M<int> mi;
上分配它不起作用,因为编译器肯定需要实例化析构函数。
到目前为止一切顺利,明确的规则。
让我们进入正题。
我写了另一个使用M
作为成员的类:
文件 X.cpp
#include "M.hpp"
struct X
{
X() = default;
~X() = delete;
private:
M<int> m_;
};
我故意删除了析构函数,因为我不希望它以任何方式干扰我的实验。 构造函数是默认的,在我的理解中,它应该只生成M<int>
的构造函数,它的唯一成员,并调用它。 令我惊讶的是,情况并非如此。X()
还尝试生成M<int>
的析构函数:
文件主.cpp
#include "X.hpp"
int main()
{
X* px = new X();
}
这是我从编译器中得到的:
$ g++ -std=c++17 main.cpp
In file included from X.hpp:1,
from main.cpp:1:
M.hpp: In instantiation of ‘M<T>::~M() [with T = int]’:
X.hpp:5:3: required from here
M.hpp:7:29: error: static assertion failed: no type can pass this
static_assert(sizeof(T) == 0, "no type can pass this");
问题是:为什么在实例化默认构造函数期间,如果不需要成员类模板的析构函数,编译器会尝试实例化它?如果确实需要,您能否指出我说明的文档?
X
的构造函数可能会调用其成员子对象的析构函数,原因很明显:如果在构造过程中发生异常,则必须销毁所有已成功构造的内容。
10.9.2 初始化基和成员
12 在非委托构造函数中,可能会调用类类型的每个潜在构造子对象的析构函数 (15.4(。[注意:此规定确保在引发异常时可以为完全构造的子对象调用析构函数(18.2(。
http://eel.is/c++draft/class.base.init#12
相关文章:
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- C++成员的析构函数顺序与shared_ptr
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 工会成员的析构函数似乎是自动调用的
- 为什么类构造函数为其成员生成析构函数?
- C++类析构函数删除成员(如果"owner"?
- C++ 在析构函数调用之前删除的动态成员数组
- 如何从类成员函数返回指针,例如 size_t * class :: function(); 并使用类析构函数 ~size
- 在这种情况下,工会成员会调用自己的析构函数吗
- 在析构函数之后,围绕成员函数的C++lambda包装器是如何工作的
- C++ 将队列作为成员的类的构造函数和析构函数
- 是否可以访问类数据成员并在析构函数中对它们执行操作?
- 使用 std::function 作为成员函数,它捕获"this",并在析构函数之后从复制的 lam
- 如何在析构函数中执行一些代码*在*成员被销毁之后
- 应该在成员对象上调用析构函数
- 如何为包含map<int,*double>成员的类编写析构函数?
- 为什么在这里调用析构函数,以及在调用该对象析构函数后如何调用对象成员函数?
- 使用线程销毁类析构函数中的shared_ptr成员变量
- C++ 类析构函数删除部分但不是全部成员数据
- 即使没有析构函数,非静态类成员也会被销毁吗?