2009-10-22 60 views
2

假設我們有類的層次結構,我們希望使它們只在整個內存管理器中分配/釋放內存。什麼是經典的C++方法來實現這種行爲? 它是一個MUST有額外的檢查,如:運算符new/delete和類層次結構

class Foo{ 
    public: 
    virtual ~Foo(){} 
    void* operator new(size_t bytes) 
    { 
    if (bytes != sizeof(Foo)){ 
     return ::operator new(bytes); 
    }  
    return g_memory_manager.alloc(bytes); 
    } 
    void operator delete(void *space, size_t bytes) 
    { 
    if (bytes != sizeof(Foo)){ 
     return ::operator delete(space); 
    } 
    g_memory_manager.dealloc(space, bytes); 
    } 
} 

回答

2

否檢查是不必要的。

看看Alexandrescu的Loki's SmallObject allocator,您只是從SmallObject繼承而來,它爲您做了所有繁重的工作!

而且不要忘了超負荷的新的所有版本和刪除:

  • 簡單的版本
  • 陣列版本
  • 安置版本

否則,你可能有一些麻煩。

+0

感謝大家的澄清。 – varnie 2009-10-22 18:34:21

+0

這些檢查在世界上怎麼可能是不必要的? – sbi 2009-10-23 10:22:35

+0

哦,等等,我想我知道你的意思:如果(且僅當)使用的分配器可以傳遞任意大小的內存塊時,這些檢查是不必要的。我的工作假設一個特定類的分配器只能提供一個大小的塊,因爲這可以實現非常快速的分配/釋放。現在,看看varnie的代碼,我發現他的分配器需要一個大小參數,所以限制似乎不適用。 – sbi 2009-10-23 10:25:57

0

我的意見:

使創作者做的事情,例如:

template<class t> 
struct creator_new { // a creator using new()/delete() 
    static t *Create(void) 
    { 
     return new t; 
    } 
    static void Destroy(t *p) 
    { 
     delete p; 
    } 
}; 

可以擴展的創造者檢查內存泄漏,或使用內存池管理對象等。

+1

但爲了防止用戶爲了測試自定義分配器是否會提高性能而不得不更改幾個100kLoC,可能會重載'new'和'delete'。另外,有時不能更改代碼。 (因爲它可能是你的客戶的代碼。)隨着重載,你可以做到這一點,只需在一個類中引入兩個函數,而不必觸摸任何用戶代碼。 – sbi 2009-10-22 14:25:19