【问题标题】:Why does static_cast(*this) to a base class create a temporary copy?为什么 static_cast(*this) 到基类会创建一个临时副本?
【发布时间】:2012-01-31 18:23:01
【问题描述】:

我正在阅读 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(上面的代码)会创建一个新副本?为什么不直接使用对象的基类部分?

【问题讨论】:

  • 如果它被转换为static_cast&lt;Window&amp;&gt;(*this).onResize();,那么我认为它会使用当前对象。 (注意&amp;)。不过不确定。
  • static_cast(this)->onResize();也应该工作,但当然 Window::onResize();这里是正确的。

标签: c++ casting effective-c++


【解决方案1】:

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

你想要的是这样的:

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

这意味着我想从*this 创建一个Window&amp; — 这是一个从一个派生类的隐式转换'参考*thisSpecialWindow&amp;)到 Window&amp; 引用。

不过,最好调用具体版本的成员函数 onResize()你要调用:

Window::onResize(); // equivalent to this->Window::onResize();

【讨论】:

  • '为什么不只使用对象的基类部分?'​​——这不是真正的答案'因为标准规定了这种方式!' ?它可以做不同的事,但这就是我们需要忍受的——无论好坏(实际上它打破了我通过指向虚拟基成员函数的函数指针来解决问题的尝试,这让我在这里偶然发现...)。
【解决方案2】:

这是因为代码转换为值 Window 而不是引用 Window&amp;。根据标准,这种形式的强制转换相当于调用 (C++11 §5.2.9/4 = C++03 §5.2.9/2)

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

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

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

Window::onResize();

)

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      对比度:

      static_cast<Window>(*this)
      

      与:

      static_cast<Window&>(*this)
      

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

      【讨论】:

        猜你喜欢
        • 2014-10-29
        • 2022-07-29
        • 2012-09-19
        • 1970-01-01
        • 1970-01-01
        • 2014-06-30
        • 2021-10-12
        • 2018-09-20
        • 1970-01-01
        相关资源
        最近更新 更多