为什么static_cast(*this)到基类创建临时副本?

pur*_*uck 20 c++ casting effective-c++

我正在阅读Effective C++并遇到了这个例子:

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

  ...

};
Run Code Online (Sandbox Code Playgroud)

这本书说:

您可能没想到的是它不会在当前对象上调用该函数!相反,强制转换创建了*this的基类部分的新临时副本,然后在副本上调用onResize!

为什么static_cast(上面的代码)创建一个新副本?为什么不只是使用对象的基类部分?

sbi*_*sbi 31

因为此代码要求创建一个新对象.此代码想使一个Window从对象*this-这可以用做拷贝构造函数Window.

你想要的是这样的:

static_cast<Window&>(*this).onResize(); 
//                ^
//                note the &
Run Code Online (Sandbox Code Playgroud)

这意味着我想创建一个Window&from *this- 这是派生类' reference(*this是a SpecialWindow&)到Window&引用的隐式转换.

但是,最好只调用 onResize()要调用的成员函数的特定版本:

Window::onResize(); // equivalent to this->Window::onResize();
Run Code Online (Sandbox Code Playgroud)


ken*_*ytm 8

那是因为代码正在转换为值Window而不是引用Window&.根据标准,这种形式的铸造相当于调用(C++11§5.2.9/ 4 = C++03§5.2.9/ 2)

Window __t (*this);
__t.onResize();
Run Code Online (Sandbox Code Playgroud)

它调用复制构造函数Window,并在该副本上执行onResize.

(调用超类方法的正确方法是

Window::onResize();
Run Code Online (Sandbox Code Playgroud)

)