2012-02-15 68 views
2

我所試圖做的是創建一個基類,用於從它派生的任何內容都會自動與其他類被註冊,如:在基類構造函數中使用`this`是否有效?

class System; 
class Object 
{ 
public: 
    Object() 
    { 
     System sys; 
     sys.AddObject(this); 
    } 
    virtual ~Object() 
    { 
     System sys; 
     sys.RemoveObject(this); 
    } 
}; 
class System 
{ 
public: 
    // Some other processing function which operates on all things derived 
    // from Object at one time. 
    void ProcessAllObjectsInExistence(); 

    void AddObject(Object *o) 
    { 
     list.push_back(o); 
    } 
    void RemoveObject(Object *o) 
    { 
     std::vector<Object *>::iterator i = find(list.begin(), list.end(), o); 
     if (*i != list.end()) list.erase(i); 
    } 
private: 
    static std::vector<Object *> list; 
}; 

這是法律和規定?我之所以問這個問題,是因爲我從ProcessAllObjectsInExistence()裏面讀取並寫入Object(此處未顯示)的數據成員後,發現一些有趣的錯誤。

即用於單個Object之前我請System.ProcessAllObjectsInExistence()成員是0100,然後內部ProcessAllObjectsInExistence(),第一行是它打印的成員和顯示00調試線。痛苦的> <

+1

請問爲什麼你沒有使'AddObject'和'RemoveObject'靜態?如果他們只使用靜態的'list'變量,那麼我認爲沒有理由他們不可能是靜態的。 – 2012-02-15 09:34:35

+0

這是完整的嗎? 「對象」的構造函數是否會在*將自身添加到列表之後做些什麼? @Joachim:它被稱爲「Borg」模式,至少這就是Alex Martelli在Python中稱之爲特定版本的模式。 – 2012-02-15 09:40:08

+1

@JoachimPileborg隱藏的靜態和'System'的不同實例令人困惑。如果他要走這條路線,那麼'系統'應該是一個單身人士,清楚地表明實際上只有一個有效的實例。 (不管是否只有一個實例,因爲他這樣做是合適的,還有另外一個問題,我們沒有足夠的信息來判斷它) – 2012-02-15 09:57:23

回答

3

在基類內引用this是完全有效的。
但是,在Base類中調用虛擬方法(如果有的話)實際上不會按照您認爲的方式工作。

4

是的,在構建基類時訪問this是明確定義的。

有一點要注意的是,一個構造函數(或析構函數)期間的*this類型是類目前正在建設中,的類型完全構造的對象將最終擁有。這樣做的主要含義是虛擬函數將根據它們在基類中的定義進行調度,並且調用純虛函數是無效的。

當然,調用AddObject是好的,因爲它沒有訪問正在建設中的對象。我可以看到你的代碼出錯的唯一方法是,如果你在構造一個對象時從另一個線程調用ProcessAllObjectsInExistence()--這會非常糟糕,因爲沒有鎖來保護對列表的訪問。

+0

只要它[有一個實現](http://stackoverflow.com/questions/2089083/),你可以調用一個純虛函數,對吧? – fredoverflow 2012-02-15 10:48:32

+0

@FredOverflow:只有靜態調用它('Base :: fn()')。幾乎調用它(只是'fn()')總是未定義的行爲。 – 2012-02-15 11:06:09

相關問題