加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 10:35:45 所属栏目:百科 来源:网络整理
导读:从§5.3.5[expr.delete] / 1,我可以理解,对象* a的析构函数不会在下面的代码段中调用.但是我不明白为什么在这种情况下会调用类成员B的析构函数,这可以在 live example中看到. #include iostreamclass A{public: class B{ public: ~B(){ std::cout "B dtor" '
从§5.3.5[expr.delete] / 1,我可以理解,对象* a的析构函数不会在下面的代码段中调用.但是我不明白为什么在这种情况下会调用类成员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.

在这种情况下,您的A类可以隐式转换为B *,这正是您删除* a时所发生的情况.

换句话说,您的删除* a实际上被解释为

delete (*a).operator B*();

你在代码中删除了B,而不是A.这就是调用B的析构函数的原因.

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

delete a;

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读