class 成员 `B` 的析构函数,为什么在下面的代码片段中调用了它?
The destructor for the class member `B`, why is it invoked in the snippet below?
从 §5.3.5[expr.delete]/1,我可以了解到对象 *a
的析构函数是 not 在片段中调用以下。但是我不明白为什么在这种情况下会调用 class 成员 B
的析构函数,如 live example.
中所示
#include <iostream>
class A
{
public:
class B{ public: ~B(){ std::cout << "B dtor" << '\n'; } };
A() { p = new B(); }
operator B*() { return p; }
private:
B* p;
};
int main()
{
A* a = new A();
delete *a;
std::cout << "end" << '\n';
}
希望标准引用一些解释这一点的内容。
您的 delete *a
将运算符 delete
应用于类型 A
的 非指针 表达式 *a
。唯一合法的方法是类型 A
可以隐式转换为某种指针类型。
5.3.5 Delete [expr.delete]
1 ... The operand shall have a pointer to object type, or a class type having a single non-explicit conversion
function (12.3.2) to a pointer to object type.
2 If the operand has a
class type, the operand is converted to a pointer type by calling the
above-mentioned conversion function, and the converted operand is used
in place of the original operand for the remainder of this section.
在这种情况下,您的 class A
可以隐式转换为 B *
,这正是您执行 delete *a
.
时发生的情况
换句话说,你的delete *a
实际上被解释为
delete (*a).operator B*();
在你的代码中是B
你delete
,而不是A
。这就是调用 B
的析构函数的原因。
如果你想销毁 A
对象,你必须做
delete a;
(注意,没有 *
)。那不会调用 B
的析构函数。
如果您尝试实现智能指针 - 那么您可能应该检查 boost sources
简而言之,智能指针模式提供了一些小对象的概念,它包装原始对象并在不需要时将其销毁。
例如非常简单的例子,也没有自定义删除器等:
<template class T>
class scope_delete
{
public:
scope_delete(T* ptr) : p(ptr) {}
~scope_delete() { delete p; }
T* operator->() { return p; }
private:
T * p;
};
// somewere in programm
{
auto obj = scope_delete(new MyCLasss);
obj->some_fun();
} // here stack object obj will be deleted and remove original object.
要了解详细信息,您应该阅读一些书籍,或者我只是 google 这个 article。
从 §5.3.5[expr.delete]/1,我可以了解到对象 *a
的析构函数是 not 在片段中调用以下。但是我不明白为什么在这种情况下会调用 class 成员 B
的析构函数,如 live example.
#include <iostream>
class A
{
public:
class B{ public: ~B(){ std::cout << "B dtor" << '\n'; } };
A() { p = new B(); }
operator B*() { return p; }
private:
B* p;
};
int main()
{
A* a = new A();
delete *a;
std::cout << "end" << '\n';
}
希望标准引用一些解释这一点的内容。
您的 delete *a
将运算符 delete
应用于类型 A
的 非指针 表达式 *a
。唯一合法的方法是类型 A
可以隐式转换为某种指针类型。
5.3.5 Delete [expr.delete]
1 ... The operand shall have a pointer to object type, or a class type having a single non-explicit conversion function (12.3.2) to a pointer to object type.
2 If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section.
在这种情况下,您的 class A
可以隐式转换为 B *
,这正是您执行 delete *a
.
换句话说,你的delete *a
实际上被解释为
delete (*a).operator B*();
在你的代码中是B
你delete
,而不是A
。这就是调用 B
的析构函数的原因。
如果你想销毁 A
对象,你必须做
delete a;
(注意,没有 *
)。那不会调用 B
的析构函数。
如果您尝试实现智能指针 - 那么您可能应该检查 boost sources
简而言之,智能指针模式提供了一些小对象的概念,它包装原始对象并在不需要时将其销毁。
例如非常简单的例子,也没有自定义删除器等:
<template class T>
class scope_delete
{
public:
scope_delete(T* ptr) : p(ptr) {}
~scope_delete() { delete p; }
T* operator->() { return p; }
private:
T * p;
};
// somewere in programm
{
auto obj = scope_delete(new MyCLasss);
obj->some_fun();
} // here stack object obj will be deleted and remove original object.
要了解详细信息,您应该阅读一些书籍,或者我只是 google 这个 article。