25

我正在阅读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

  ...

};

书上说:

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

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

4

4 回答 4

33

因为这段代码要求创建一个新对象。这段代码想要创建一个Window对象——*this这可以使用.Window

你想要的是这样的:

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

这意味着我想创建一个Window&from *this——这是从派生类的引用( is a ) 到引用的隐式转换*thisSpecialWindow&Window&

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

Window::onResize(); // equivalent to this->Window::onResize();
于 2012-01-31T18:27:05.967 回答
8

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

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

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

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

Window::onResize();

)

于 2012-01-31T18:28:18.220 回答
2

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

于 2012-01-31T18:27:23.663 回答
1

对比:

static_cast<Window>(*this)

和:

static_cast<Window&>(*this)

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

于 2012-01-31T18:31:33.910 回答