2013-07-30 18 views
0

我有一個簡單的C++類,我需要知道某個對象是否應該在程序中的某個位置被刪除或不被刪除。該機制應該跨平臺和現代C++編譯器可移植。確定一個對象是否是動態分配的或不在C++中

這樣做的一個方法可以讓我想到的是:有未通過構造函數初始化,而是由重載運營商分配新成員字段,例如:

class message 
{ 
protected: 
    int id; 
    bool dynamic; 
public: 
    message(int _id): id(_id) 
    { 
     // don't touch `dynamic` in the constructor 
    } 

    void* operator new(size_t size) 
    { 
     message* m = (message*)::operator new(size); 
     m->dynamic = true; 
     return m; 
    } 

    void operator delete(void* m) 
    { 
     if (((message*)m)->dynamic) 
      ::operator delete(m); 
    } 
}; 

除了形成它「感覺」錯誤,這種方法有什麼問題?

編輯:應該提到的是,對象是動態或靜態的(並且決不堆棧的局部),因此保證是任一調零或new初始化。

+11

*爲什麼*你需要這個嗎?我可以保證這是一種錯誤的方式,即使有辦法做你所問的事情(我相當確定沒有)。你不應該在運行時決定是否刪除一個指針,因爲你應該知道(編輯:在設計時,即就程序而言是先驗的)誰擁有什麼,它的生命週期是什麼。 – delnan

+1

使析構函數爲'private'。那麼答案總是「是」。 –

+0

@delnan:不,你不能保證:)這是一個優化問題。我有一個消息隊列,有很多消息傳遞;在某些情況下,它們是動態分配的,但在其他一些情況下,爲了優化起見,我可以重新使用靜態對象(當然,確保靜態對象只進入一次消息隊列)。 – mojuba

回答

3

構造函數需要設置dynamic爲false,然後,而不是覆蓋new,你需要像一個靜態方法:

static message *createMessage(int _id) 
{ 
    message *ret = new message(_id); 
    ret->dynamic = true; 
    return ret; 
} 

然後調用該方法,而不是new荷蘭國際集團一message

+0

但它總是被覆蓋,不是嗎? – delnan

+0

只有在調用'new'時。如果是堆棧分配,'dynamic'將保持設置爲'false'。 –

+2

@JimBuck:不,構造函數在* operator new之後運行*,所以即使operator new設置dynamic爲true,構造函數也會用false替換它。 –

3

不要這樣做。除了它不起作用的事實之外,對象不應該管理自己一生的任何事情。您可以將unique_ptrshared_ptr用於自定義刪除程序,並且如果該對象是堆棧分配的,則您可以在其分配站點上知道;在這種情況下,您可以提供如下的無操作刪除程序:

struct null_deleter { 
    template<class T> 
    void operator()(const T*) const {} 
}; 
+0

您可能不會遇到問題。在我的情況下,消息對象被處理,並可能在我的程序中的一個點被銷燬,而它們可以在許多不同的地方創建。我想通過儘可能重新使用靜態消息對象來優化我的消息隊列,即當消息只保證一次進入隊列時。這是一個優化問題。所以不,這是一個運行時間而不是編譯時間。 – mojuba

+1

@mojuba:如果他沒有得到它,那是因爲你沒有說出問題中的含義。 – GManNickG

相關問題