如何为以后的安置新分配“如同新的”

问题描述 投票:0回答:1

我们需要将一些堆存储的分配和初始化分开。不幸的是,客户端代码使用

delete p;
来删除指针。如果我们可以控制删除,我们可以使用
::operator new (sizeof(T), std::align_val_t(alignof(T)))
进行分配,然后使用放置
new
和相应的全局
::operator delete
。但是(如果我理解正确的话)
delete
可能会调用
T::operator delete
,可能需要来自
T::operator new
的分配,如果存在多个重载,则
T::operator new
T::operator delete
的不同可能参数之间具有复杂的优先顺序.

是否有类似

std::allocate_as_if_by_new<T>()
的东西会执行与
new T(...)
完全相同的分配,但无需初始化,或者至少保证(初始化后)
delete p;
会正确地释放它?

c++ dynamic-memory-allocation unique-ptr
1个回答
0
投票

不。 你能做的最好的事情就是使用像句柄这样的习惯用法。

句柄习惯用法是指您传递的值不是指向实际数据的真实指针。 您可以通过让句柄具有您控制的析构函数来允许删除它。

struct Interface {
  virtual void DoStuff() const = 0;
  virtual ~Interface() {}
};

struct Forwarder:Interface {
  virtual void DoStuff() const { return pImpl->DoStuff(); }
  Interface* pImpl = 0;
  ~Forwarder() {
    /* delete pImpl using your internal mechanism */
  }
};

然后从您的 API 返回

new Forwarder{ pRealObject }

它们

delete
Forwarder
对象,它对您的实际底层对象
pImpl
进行适当的清理。 如果它有一个虚拟函数表,您的
Forwarder
实现只会将所有内容都反弹到搞乱
pImpl

如果它没有虚函数表(例如,ADT 中的自由函数),您可以教这些 ADT 将参数转换为

Forwarder*
,然后使用
pImpl
代替。

© www.soinside.com 2019 - 2024. All rights reserved.