【问题标题】:Virtual function of derived class calls that of base class派生类的虚函数调用基类的虚函数
【发布时间】:2020-07-10 01:43:06
【问题描述】:
#include <iostream>
using namespace std;
class Widget {
public:
    int width;
    virtual void resize() { width = 10; }
};
class SpeWidget :public Widget {
public:
    int height;
    void resize() override {
        //Widget::resize();
        Widget* th = static_cast<Widget*>(this);
        th->resize();
        height = 11;
    }
};
int main() {
    //Widget* w = new Widget;
    //w->resize();
    //std::cout << w->width << std::endl;
    SpeWidget* s = new SpeWidget;
    s->resize();
    std::cout << s->height << "," << s->width << std::endl;
    std::cin.get();
}

派生类 (SpeWidget) 虚函数 (resize()) 想在基类 (Widget) 中调用它。为什么上面的代码有段错误。谢谢!

【问题讨论】:

  • 见:Can I call a base class's virtual function if I'm overriding it?。因为resizevirtual,即使你通过Widget* 调用它,它也会从派生类SpeWidget 调用“正确”函数。从超类调用方法的正确语法是Widget::resize()。也就是说,你可以写void resize() override { Widget::resize(); height = 11; },或者void resize() override { this-&gt;Widget::resize(); height = 11; },如果你愿意的话。
  • this-&gt;Widget::resize() 解释清楚,我想。

标签: c++ virtual-functions


【解决方案1】:

注释掉的代码是对的。

Widget::resize();

您的替代代码错误。

Widget* th = static_cast<Widget*>(this);
th->resize();

想一想:您正在通过指向基类的指针调用虚函数。当你用任何虚函数这样做时会发生什么?它调用了最衍生的版本。换句话说,无限递归。

【讨论】:

  • 这是有道理的。我认为另一种解释是ththisstatic_cast 之后的副本。然后th-&gt;resize()不能改变this的内容。
  • 如果这可以帮助您思考,那就太好了。请记住:通过指针调用虚函数总是通过 vtable,这意味着它总是调用最派生的版本。没有办法避免它。但是直接调用 named 版本(即 'Widget::resize()' )会强制调用特定版本(基类版本)。
猜你喜欢
  • 2011-09-27
  • 2019-04-19
  • 2015-10-24
  • 2015-04-16
  • 2011-09-08
  • 1970-01-01
  • 2013-08-25
  • 1970-01-01
  • 2019-01-09
相关资源
最近更新 更多