2010-04-14 45 views
1

我有一個GUI架構,其中元件火災事件,像這樣:訪問隱藏的「這個」指針

guiManager->fireEvent(BUTTON_CLICKED, this); 

每一個事件燒製通行證「這個」作爲事件的調用者。從來沒有一次我想通過'這',並進一步,沒有指針除了因爲'這個'應該通過。

這使我想到了一個問題:我如何可以斷言,fireEvent是從來沒有比「這個」其他指針,我怎麼能簡化(和同質化)調用fireEvent只是:

guiManager->fireEvent(BUTTON_CLICKED); 

在這一點上,我想起一個相當常見的編譯器錯誤的,當你寫的東西是這樣的:

class A { 
public: 
    void foo() {} 
}; 

class B { 
    void oops() { const A* a = new A; a->foo(); } 
}; 

int main() { 
    return 0; 
} 

編譯這會給你

In member function ‘void B::oops()’: error: passing ‘const A’ as ‘this’ argument of ‘void A::foo()’ discards qualifiers

因爲成員函數將'this'作爲隱藏參數傳遞。

「啊哈!」我說。這(沒有雙關語意圖)正是我想要的。如果我能以某種方式訪問​​隱藏的'this'指針,它將解決我前面提到的兩個問題。問題是,據我所知你不能(可以嗎?),如果可以的話,會出現「但它會破壞封裝!」除了我已經每次都傳遞'this'之外,它還有什麼可以突破的。

那麼,還有一種方法可以訪問隱藏的'this',如果沒有任何習語或替代方法比每次傳遞'this'更優雅?

+3

關於對'A :: foo'調用的錯誤信息中的'this'是成員函數被調用的'a'對象(該對象,它將在'A :: foo功能)。它不是指'B :: oops'中的'this'。 – sth 2010-04-14 16:31:04

+0

我只是自己重讀錯誤,特別是它說「傳遞const A」的部分,並且實現了同樣的事情。有時候,非常非常小心地閱讀內容會有所幫助。所以我的'隱藏這個'指針的整個概念在開始時是錯誤的。噢,如果其他人對錯誤信息做出同樣的錯誤結論,我會留下未編輯的原始問題。 – Kyle 2010-04-14 16:37:14

回答

6

您可以定義

void Element::fireEvent(EVENT e) { 
    guiManager->fireEvent(e, this); 
} 

保存自己有點每次寫的。因爲guiManager需要知道哪個Element調用了fireEvent,所以你必須用this來調用一些點。

1

我不知道我理解你的問題的後半部分(和一件事情的時間是一個很好的規則在這裏),但在的情況下:

guiManager->fireEvent(BUTTON_CLICKED, this); 

你可以給這個類代碼是從一個以guiManager作爲參數的構造函數調用的 - 稱之爲mGM。然後提供一個成員函數,看起來像這樣:whicch呼叫您

void FireEvent(EventType e) { 
    mGM->fireEvent(e, this); 
} 

FireEvent(BUTTON_CLICKED); 
1

它依賴的guiManager的範圍。

你可以把它改寫:

class MyClass 
{ 
public: 

private: 
    void FireEvent(GuiManager* guiManager, EventType e) 
    { 
    assert(guiManager); 
    guiManager->FireEvent(e, this); 
    } 
}; 

是否有一個原因傳遞this(的MyClass*類型),而不是*this(的MyClass&型)?如果你傳遞一個指針,這意味着你期望對象可能是NULL ...並且this永遠不是NULL(禁止未定義行爲的危險利用)

0

另一種選擇是創建一個#define宏,以便編譯器將添加「這個」參數適合你。這將是這個樣子:

#define FIREEVENT(gm,e) gm->fireEvent(e, this) 
FIREEVENT(guiManager, BUTTON_CLICKED); //compiles as: guiManager->fireEvent(BUTTON_CLICKED); 

雖然,我不建議這樣做,我傾向於畏縮隨時我看到C++宏,因爲它們通常使代碼更難理解,並可能導致真正令人困惑的編譯器錯誤。