2012-01-31 252 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不是。这有帮助吗?

相关问题