[英]How to assign a destructor to a pointer?
我正在编写一个 memory 管理库,需要显式调用析构函数,在我的设计中,我有一个指向 object 的析构函数方法的指针,我编写如下代码:
void (*p)() = foo.~Foo;
但我得到了
错误:无法将 'Foo::~Foo' 从类型 'void (Foo::)() noexcept' 转换为类型 'void (*)()'
我尝试了其他一些格式,例如void (Foo:: (*p))() noexcept = foo.~Foo;
但失败了。
那么将析构函数分配给指针的正确方法是什么?
编辑:在运行时我的代码不知道它在我的堆中是什么类型,所以我不能使用 foo.~Foo()。 我需要一个适合所有析构函数的生成指针,这可能吗?
不允许使用析构函数的地址。
但是,您可以制作一个非常简单的模板 function 并使用它来代替:
template<class T>
void destruct(const T* x) {
x->~T();
}
现在,只需从以下位置获取指针:
destruct<Foo>
您可以使用例如。 如果您需要绑定到实际的 object,请使用std::bind
(或 lambda):
std::bind(&destruct<Foo>, foo_ptr);
请注意,一旦绑定,它就不能转换为原始的 function 指针。
对不起,你不能。 您不能根据[class.dtor]/2 获取析构函数的地址:
析构函数用于销毁其 class 类型的对象。 不应采用析构函数的地址。 可以为
const
、volatile
或const volatile
object 调用析构函数。const
和volatile
语义 ([dcl.type.cv]) 不适用于正在破坏的 object。 当派生最多的 object 的析构函数启动时,它们停止生效。
我需要一个适合所有析构函数的生成指针,这可能吗?
不它不是。 就像它不会与任何其他成员 function 一样。
要在 object 上调用 function,您需要知道 object 的类型。
而且,由于您无法获取析构函数的地址,因此您甚至无法在“数据库”中存储/注册一个。 然而,正如 Paul 所展示的,您可以存储一个函子来完成这项工作。 为每个正在使用的 object 注册这些会有点难看,但是当您尝试重新发明类型系统时会发生这种情况!
我强烈建议不要使用类型擦除(改用一些不错的 inheritance 怎么样?),不要自己调用析构函数。
请记住,析构函数当然是成员 function,因此您需要两个指针:一个指向 object,一个指向成员 ZC1C425268E68385D1AB5074C17A94F4 的偏移量(在这种情况下为析构函数)。
要获取对象的地址很简单,只需使用std::addressof()
。
但是要获得析构函数,您需要一个包装器 function 来调用给定对象地址的析构函数,因为您不能获取析构函数的地址。
所以使用像Herb Sutter建议的东西(感谢@LightnessRacesinOrbit 和@Croolman 的评论):
[](const void* x) { static_cast<const Foo*>(x)->~Foo(); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.