【问题标题】:operator delete - how to implement?运算符删除 - 如何实现?
【发布时间】:2014-12-09 15:56:49
【问题描述】:

我知道在正常情况下如何处理内存释放。我的情况略有不同。

我正在实现自己的内存池。我希望我班的客户尽可能接近一般的分配和取消分配方法。

inline void* operator new(size_t dead_param, CPool&  objPool)
{
    return objPool.Allocate();
}

我有这个全局函数,所以我班的用户可以简单地调用

Base baseObj = new (poolObj)Base2();

现在我不知道如何调用析构函数?我显然没有任何想法

虽然我有全局操作符删除

inline void operator delete(void* ptr, CPool& objPool)
{
    objPool.DeAllocate(ptr);
}

请指导..我怎样才能从客户端代码中调用这个函数?从用户端对语法进行最小的更改。另请注意,我不希望我的代码的用户实现operator newoperator delete 并从那里调用AllocateDeAllocate

【问题讨论】:

  • 为什么不让人们打电话给Base* baseObj = poolObj.Allocate();
  • 客户端的语法看起来有点难看。 Base* baseObj = (Base*) poolObj.Allocate()。哎呀..类型转换...虽然我一直作为最后的手段..而且由于无法调用此函数,我现在很好奇..
  • 只有在构造函数因异常退出时,才会从 Placement new 内部调用 Placement delete。在所有其他情况下,调用“正常”operator delete(void*)。您应该将足够的信息存储到分配的内存块中,以便以后能够释放它,而无需额外的输入。通常,分配器会在它返回的指针的负偏移处写入附加信息。

标签: c++ memory-management new-operator delete-operator


【解决方案1】:

简而言之:使用placement new 是唯一可以显式调用析构函数的情况:

baseObj->~Base();

但这看起来很奇怪,因为使用你的内存池,你实际上是在让最终用户做所有的簿记......这使得你的内存池类并不比仅仅使用 std 更好(并且可以说更糟) ::矢量。

我不会让用户自己进行新的放置...相反,如果提供您自己的内存池,则应该使用 ObjectPool 类来完成:

class ObjectPool {
  public:
    template <typename T, typename... A>/*c++ 11 ftw*/
    T* allocate(A... args) {
       void* create_location;//pool figures out where this is, probably with sizeof<T>

       return new (create_location) T(args...);
     }
     template <typename T>
     void dellocate(T* t) {
         t.~T();//With placement new, this is the one place this is OK
         //pool marks that memory as avaiable to be allocated in
     }
 }

老实说,这是让您的池拥有更多实用程序的唯一方法,而最终用户只是制作自己的std::vector&lt;uint8_t&gt;

应该注意的是,这并不能阻止 T 在堆上分配其他任何东西...

【讨论】:

猜你喜欢
  • 2018-01-19
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 2016-05-25
  • 2020-01-23
  • 2017-04-23
  • 2011-07-14
  • 2013-03-17
相关资源
最近更新 更多