繁体   English   中英

如何将析构函数分配给指针?

[英]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 类型的对象。 不应采用析构函数的地址。 可以为constvolatileconst volatile object 调用析构函数。 constvolatile语义 ([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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM