从§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';
}
非常感谢标准中的一些引用解释这一点。
答案 0 :(得分:13)
您的delete *a
将运营商delete
应用于*a
类型的非指针表达式A
。唯一可以合法的方法是类型A
可以隐式转换为某种指针类型。
5.3.5删除[expr.delete]
1 ...操作数应具有指向对象类型的指针,或具有单个非显式转换的类类型 函数(12.3.2)指向对象类型的指针。
2 如果操作数有 类类型,操作数通过调用转换为指针类型 上述转换函数,使用转换后的操作数 代替本节其余部分的原始操作数。
在这种情况下,您的班级A
可隐式转换为B *
,这正是您执行delete *a
时所发生的情况。
换句话说,您的delete *a
实际上被解释为
delete (*a).operator B*();
代码中B
delete
,而不是A
。这就是调用B
的析构函数的原因。
如果你想销毁A
对象,你必须做
delete a;
(注意,没有*
)。那不会叫B
的析构函数。
答案 1 :(得分:0)
如果您尝试实现智能指针 - 那么您可能应该检查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.
有关详细信息,您应该阅读一些书籍,或者我只是谷歌这个article。