Class 并且成员析构函数调用了两次
Class and member destructors called twice
class A
{
public:
~A()
{
std::cout << "A destroyed" << std::endl;
}
};
class B
{
public:
A a;
~B()
{
std::cout << "B destroyed" << std::endl;
}
};
int main()
{
B b;
b.~B();
}
输出:
B destroyed
A destroyed
B destroyed
A destroyed
谁能给我解释一下这是怎么回事?我预计输出为
B destroyed
A destroyed
(调用 ~B() 一次,调用 ~A() 一次)。
在有限范围内创建的任何对象都将在退出范围时销毁。
意思是,如果您在堆栈 上创建了一个对象 ,它将在堆栈折回时与声明的任何其他变量一起被销毁在那个范围内。
唯一的例外是当您使用对象的动态分配时,使用关键字 new
,这会在 堆[=25= 上创建对象],它不会自行清理。但即便如此,调用 delete
也会自行调用析构函数。
话虽如此,为了避免使用 new
和 delete
,以及为了更好的资源管理,有些类型(例如智能指针)可以自行处理这些问题,在一种称为资源分配即初始化(或 RAII)的技术,它使事情变得更加简单(并且您进入了第一部分,所有内容都在堆栈上分配,因此在折叠时会自动调用析构函数)。
class A
{
public:
~A()
{
std::cout << "A destroyed" << std::endl;
}
};
class B
{
public:
A a;
~B()
{
std::cout << "B destroyed" << std::endl;
}
};
int main()
{
B b;
b.~B();
}
输出:
B destroyed
A destroyed
B destroyed
A destroyed
谁能给我解释一下这是怎么回事?我预计输出为
B destroyed
A destroyed
(调用 ~B() 一次,调用 ~A() 一次)。
在有限范围内创建的任何对象都将在退出范围时销毁。 意思是,如果您在堆栈 上创建了一个对象 ,它将在堆栈折回时与声明的任何其他变量一起被销毁在那个范围内。
唯一的例外是当您使用对象的动态分配时,使用关键字 new
,这会在 堆[=25= 上创建对象],它不会自行清理。但即便如此,调用 delete
也会自行调用析构函数。
话虽如此,为了避免使用 new
和 delete
,以及为了更好的资源管理,有些类型(例如智能指针)可以自行处理这些问题,在一种称为资源分配即初始化(或 RAII)的技术,它使事情变得更加简单(并且您进入了第一部分,所有内容都在堆栈上分配,因此在折叠时会自动调用析构函数)。