2011-07-28 37 views
5

在我的項目中,我有一個抽象基類「Base」。我想跟蹤所有從「Base」派生的對象的動態分配/釋放。爲此,我重寫了「Base」中的新/刪除操作符。在構建對象時獲取大多數派生類型

在重寫的new運算符中成功分配內存之後,我想通知用於跟蹤內存的分配已發生的對象,分配的派生類型和它的大小。大小不是問題(因爲它直接傳遞給「Base」的新運算符),但獲得最多派生類型是個問題。

我傾向於認爲這是不可能的方式我試圖做到這一點。由於對象的更多派生部分尚未構建,因此無法知道它們是什麼。然而,「Base」類重載新操作符知道最終產品的大小 - 所以有可能知道關於它的其他事情嗎?

對於背景:

void* Base::operator new(size_t size) 
{ 
    void* storage = malloc(size); 

    if (storage == NULL) 
     throw std::bad_alloc(); 

    // Notify MemoryTracker an allocation has occurred 
    // MemoryTracker::Instance().Allocate(type, size); 

    return storage; 
} 
+3

+1我不相信這是可能的使用operator new,但我不能證明它。我很好奇,看看我是否會再次被證明是錯誤的C++語言功能。 :-) – templatetypedef

回答

2

你說得對,這是不可能通過這種方式,爲new運營商只是分配內存,僅此而已。做這種事情的正確位置是構造函數,而不是分配器,在那裏你應該能夠使用RTTI來確定構建對象的類型(因此可以在Base構造函數中完成,而不是在每個子類構造函數中)。

+6

RTTI不能在基類構造函數中完全工作,因爲它基於vtable指針進行操作,該指針被初始化爲指向基類的vtable。 – unkulunkulu

+0

看起來這是真的 - 是否有可能在完全構造之前知道對象的派生類型? – Wells

+0

@井:不,它不是。在派生構造函數之前調用基類構造函數。 –

2

在學習C++的GC實現時,我學到了一個技巧。缺點是你必須使用宏而不是純新的。

struct base { 
    void *operator new(size_t sz) { 
    // ... 
    } 
}; 

struct init_tag {}; 

base * operator % (init_tag, base *ptr) { 
    // just do what you like here... 
    return ptr; 
} 

#define gc_new init_tag() % new 
+0

可怕。謝謝。 – Wells

相關問題