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

Why does static_cast(*this) to a base class create a temporary copy?

本文关键字:副本 创建 一个 static cast 为什么 this 基类      更新时间:2023-10-16

我正在阅读有效的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
  ...
};

书中写道:

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

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

因为此代码要求创建一个新对象。这段代码想要从*this生成一个Window对象——这可以使用Window复制构造函数来完成。

你想要的是:

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

这意味着我想从*this生成Window&——这是从派生类'引用(*thisSpecialWindow&)到Window&引用的隐式转换。

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

Window::onResize(); // equivalent to this->Window::onResize();
这是因为代码转换为值Window而不是引用Window&。根据标准,这种铸造形式相当于调用(C++11§5.2.9/4=C++03§5.2.9/2)
Window __t (*this);
__t.onResize();

其调用Window的副本构造函数并对该副本执行onResize。

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

Window::onResize();

)

因为您正在强制转换实际对象,而不是指针或引用。这与将double强制转换为int创建新的int的方式相同——不重用double的部分。

对比度:

static_cast<Window>(*this)

带有:

static_cast<Window&>(*this)

一个调用复制构造函数,另一个不调用。这有帮助吗?