c++ - 保存对象的析构函数地址并在以后调用它是否定义明确的行为?

标签 c++ c++11 memory memory-management

我目前正在研究用 C++ 编写的堆栈分配器。应该可以通过模板方法从此堆栈分配器获取对象。一旦调用另一个释放方法,这些对象就应该被销毁。在尝试使用不同的方法来实现析构函数的调用时,我偶然发现了以下内容:

auto destructor = someObject->~SomeClass;
destructor();

析构函数似乎是被实际调用的,但这对我来说有点奇怪。我有以下问题:

  1. 这是明确定义的行为吗?
  2. 析构函数的类型是什么(我可以用什么替换 auto 关键字)?
  3. 我能否将多个不同类型对象的所有析构函数地址保存在一个列表中,并在以后调用它们?

最佳答案

如评论所述,这是未定义的行为/编译器扩展。

虽然你可以做你想做的事:

template<typename T>
std::function<void(T*)> defer_dtor()
{
   return [](T* ptr) {ptr->~T();};
}

或直接(更像您的问题,但无法将唯一的 lambda 类型直接添加到列表中。)

auto destructor = [&]{someObject->~SomeClass();};
destructor();

注意:这跟在您的问题之后,不会调用 delete ptr。这是否合适取决于上下文,但大概如果你想包装 delete ptr 你只会使用 std::shared_ptr

[编辑] 我在你的问题中遗漏了一小部分:“将多个对象的所有析构函数地址保存在一个列表中不同类型”。

这将是一个问题。准确地说,是设计问题。这些类型有什么关系?如果通过继承,你不需要一个析构函数列表,而是一个 virtual 析构函数。如果类型不相关,您如何匹配对象和保存的析构函数?如果您确实拥有所有这些对象的类型,为什么不直接调用 ->~Type()

关于c++ - 保存对象的析构函数地址并在以后调用它是否定义明确的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43483814/

相关文章:

debugging - Visual Studio 在调试时是否显示虚拟地址或物理地址?

c++ - `const` 作为移动构造函数的模板参数的效果

c++ - 当我知道类型时,如何避免虚拟调用?

c - 如何在 mac OSX 中查找内存使用情况?

c++ - 在纯 C++ (C++11) 中扩充一个类/应用一个方面

c++ - 如何理解 `std::function` 的类型仅取决于其调用签名?

c - 如何更改存储在内存地址的值

c++ - C++在队列中查找某些元素

c++ - 如何改进自引用模板的实现?

c++ - 无法从QTreeView连接信号/插槽