0
#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(); } 

Derived class (SpeWidget) virtual function (resize()) wants to call that in base class (Widget). Why does the above code have segment fault. Thank you!

2
  • See: Can I call a base class's virtual function if I'm overriding it?. Because resize is virtual, even if you call it through a Widget* it will call the "correct" function from the derived class SpeWidget. The correct syntax for calling the method from the superclass is just Widget::resize(). That is, you write just void resize() override { Widget::resize(); height = 11; }, or maybe void resize() override { this->Widget::resize(); height = 11; }, if you want. Commented Jul 10, 2020 at 1:46
  • this->Widget::resize() is clear to explain it, I think. Commented Jul 10, 2020 at 8:52

1 Answer 1

1

The commented out code is right.

Widget::resize(); 

Your substitute code is wrong.

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

Think about it: You are calling a virtual function through a pointer to the base class. What happens when you do that with any virtual function? It calls the most derived version. In other words, endless recursion.

Sign up to request clarification or add additional context in comments.

2 Comments

That makes sense. I think another explanation is th is a copy of this after static_cast. And then th->resize() can not change the content of this.
If that helps you think about it that's great. Just remember: calling virtual functions through a pointer always goes through the vtable which means it always calls the most-derived version. There is no way to avoid it. But calling a named version directly (i.e. 'Widget::resize()' ) forces a specific version (the base class version) to be called.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.