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*();

在你的代码中是Bdelete,而不是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