2012-01-31 253 views
14

我讀有效的C++和整個這個例子就是:爲什麼static_cast(* this)給基類創建一個臨時副本?

class Window {        // base class 
public: 
    virtual void onResize() { ... }    // base onResize impl 
    ... 
}; 

class SpecialWindow: public Window {   // derived class 
public: 
    virtual void onResize() {     // derived onResize impl; 
    static_cast<Window>(*this).onResize(); // cast *this to Window, 
               // then call its onResize; 
               // this doesn't work! 

    ...          // do SpecialWindow- 
    }           // specific stuff 

    ... 

}; 

書中說:

什麼你可能想到的是,它並沒有調用當前對象上的功能!相反,該轉換會創建* this的基類部分的新臨時副本,然後調用副本上的onResize!

爲什麼static_cast(上面的代碼)創建一個新的副本?爲什麼不只是使用對象的基類部分?

+0

如果它被轉換爲'static_cast (* this).onResize();',那麼我認爲它會使用當前對象。 (注意'&')。但不知道。 – 2012-01-31 18:26:48

+0

static_cast (this) - > onResize(); 也應該工作,但當然是 Window :: onResize(); 在這裏是正確的。 – Trass3r 2013-03-08 14:27:14

回答

25

因爲這段代碼要求來創建新的對象。此代碼想從*this製作Window對象 - 可以使用Window複製構造函數完成。

你想,而不是這是什麼:

static_cast<Window&>(*this).onResize(); 
//    ^
//    note the & 

這意味着我想打一個Window&*this - 這是一個派生類參考的隱式轉換*thisSpecialWindow&)至Window&參考。

然而,最好只調用成員函數onResize()要呼叫的特定版本:

Window::onResize(); // equivalent to this->Window::onResize(); 
2

因爲你是鑄造實際的對象不是一個指針或引用。 這只是以同樣的方式鑄造doubleint創建新int - 不重用的double的一部分。

6

這是因爲代碼轉換成一值Window,而不是參考Window&。根據該標準,這種形式的澆鑄的等效於調用(C++ 11§5.2.9/ 4 = C++ 03§5.2.9/ 2)

Window __t (*this); 
__t.onResize(); 

它調用的拷貝構造Window,並在該副本上執行onResize。

(父類的方法,正確的方法是

Window::onResize(); 

1

對比度:

static_cast<Window>(*this) 

有:

static_cast<Window&>(*this) 

一個調用複製構造函數,其他d不是。這有幫助嗎?

相關問題