標籤:
static_cast(*this) to a base class create a temporary copy.
class Window { // base classpublic: virtual void onResize() { ... } // base onResize impl ...};class SpecialWindow: public Window { // derived classpublic: 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 ...};
Effective C++: What you might not expect is that it does not invoke that function on the current object! Instead, the cast creates a new, temporary copy of the base class part of *this, then invokes onResize on the copy!
*******************************************************************************************
Contrast:
static_cast<Window>(*this)
with:
static_cast<Window&>(*this)
One calls the copy constructor, the other does not.
*******************************************************************************************
Because you are casting actual object not a pointer or reference. It‘s just the same with casting double to int creates new int - not reusing the part of double.
double類型轉換為int型會建立一個新的int型變數?
*******************************************************************************************
上面的句子static_cast<Window>(*this).onResize();千萬別改成下面這樣,那樣會更悲慘!
virtual void onResize()
{
static_cast<Window*>(this)->onResize(); //調用基類的onResize()
derived_ = 2;
std::cout <<"S" << " base_=" << base_ << ",derived=" << derived_ << std::endl;
}
實際上,可能只有C的高手初轉C++,對C++對象的記憶體模型還不很清楚的情況下才會寫成這樣的代碼。
對一個指標,不論我們怎樣強制轉換,它指向的那段記憶體的內容並沒有改變。
函數把本類對象的指標強制轉換為基類對象的指標,只意味著“通過這個指標只能訪問基類的成員”了,而對象的內容並沒有改變。onResize是虛函數,調用它是先通過對象中指向虛表的指標找到虛表,然後在虛表中找到onResize函數的指標,最後通過函數指標調用函數。 this指標強制轉換後,記憶體沒有改變,所以指向虛表的指標沒有改變,所以它找到的虛表仍是衍生類別的虛表,自然找到的函數指標仍是衍生類別的onResize函數的指標,所以這裡就成了一個無窮遞迴調用,結果就是消耗完棧空間。
將函數修改為這樣:你就會看到不斷的輸出ReCall.
virtual void onResize()
{
std::cout<<"ReCall"<<endl;
static_cast<Window*>(this)->onResize(); //調用基類的onResize()
derived_ = 2;
std::cout <<"S" << " base_=" << base_ << ",derived=" << derived_ << std::endl;
}
[email protected]子類類型轉換為父類類型