类成员`B`的析构函数,为什么在下面的代码片段中调用它?

Wak*_*zil 3 c++ language-lawyer delete-operator c++14

从§5.3.5[expr.delete]/1,我可以理解,该对象的析构函数*a在下面的代码段调用.但我不明白为什么B在这种情况下调用类成员的析构函数,如本实例中所示.

#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';
}
Run Code Online (Sandbox Code Playgroud)

非常感谢标准中的一些引用解释这一点.

AnT*_*AnT 13

delete *a将运算符应用于类型delete非指针表达式.唯一可以合法的方法是当type 可以隐式转换为某种指针类型时.*aAA

5.3.5删除[expr.delete]

1 ...操作数应具有指向对象类型的指针,或具有指向对象类型的指针的单个非显式转换函数(12.3.2)的类类型.

2如果操作数具有类类型,则通过调用上述转换函数将操作数转换为指针类型,并使用转换后的操作数代替本节其余部分的原始操作数.

在这种情况下,您的类A可以隐式转换为B *,这正是您所做的事情delete *a.

换句话说,你delete *a实际上被解释为

delete (*a).operator B*();
Run Code Online (Sandbox Code Playgroud)

Bdelete的代码,而不是A.这B就是调用析构函数的原因.

如果你想破坏A物体,你必须这样做

delete a;
Run Code Online (Sandbox Code Playgroud)

(注意,不*).那不会叫做B析构函数.