Calling derived method from base class pointer vector
-
I have a base class and a bunch of derived classes from it, with a particular virtual function that is overriden in the derived classes, let's say:
class Base : public QMainWindow { protected: virtual void handleSomething() = 0; ... } class Derived1 : public Base { public: void handleSomething() override; ... } class Derived2 : public Base { public: void handleSomething() override; ... } class Derived3 : public Base { public: void handleSomething() override; ... }
To work with the derived classes, I created a pointer that collects them all, but in that case I had to declare it with the base class like this:
QVector<Base*> vector;
Now I am trying to call the overriden methods in a loop like this:
foreach(auto widget, vector) { widget->handleSomething(); }
But I get the following error:
'handleSomething' is a protected member of 'Base'
which means that the loop is trying to call the base method instead of the derived ones. How could I do to call the overriden methods?
-
@diego-qt
I am not as knowledgeable about C++ as some experts here, so I stand to be corrected. However, so far as I can see the behaviour is correct. If the base virtual method is protected then you can only call that from within/derived/friend of the base class. The fact that you choose to declare overrides of the base protected as public is neither here nor there. You could call them (the publics) from the outside world, but not via the base.If you are looking for a workaround you could
dynamic_cast<>
(orqobject_cast<>
) your widget to find the correct derived class and then call that way, because then the method is public. But of course that is not as neat as via the base class, and requires the caller to know about all the derived classes. -
-
@diego-qt said in Calling derived method from base class pointer vector:
setting them as protected so the derived classes can override them
All
virtual
methods can be overridden (evenprivate
), the issue is where you can call them from.private
=> base class only,protected
=> derived classes too,public
=> outside world too. You want to callwidget->handleSomething();
, so you needpublic
.I didn't suggest changing the base to
public
as I assumed the point was that yourBase
class virtual method had been writtenprotected
by someone else and had to stay like that! -
You could try
widget->Derived1::handleSomething();
to call the function from your derived class, even tho it would break your variability, because you have to decide what derived class you want to call in yourforeach
loop.
(Don't even know if it would work in your case)I would make it public (like you already did) in
Base
to avoid the issues @JonB and @jsulm stated above. -
To continue the same way as @JonB
I think the reason is that C++ is not a dynamic language as objectiveC or Java,foreach(Base* widget, vector) / I hate auto !!! { widget->handleSomething(); }
Here C++ see widget is a Base instance and when the compiler looks at the handle method, it sees it as protected and stop at it with an error.
C++ is not so smart :)