If I have the following override of a virtual event:
void derivedClass::method(event)
{
// my stuff
baseClass::method(event); // <--
}
what does the // <--- line does? What does it call? I don't think it calls the base class' method because it's virtual (so no body)
As you are suggesting, it calls the base class' method. The fact that it is virtual it only means it can be overridden and still access to the derived class' method from a pointer/reference to the base class.
The reason to do that can be easily seen with an example:
class Base {
public:
virtual void foo() {
/* do some generic stuff */
}
};
class Derived : public Base {
public:
void foo() {
/* do some specific stuff */
/* if you also want to do the generic stuff,
you can call the same method from the base class. */
Base::foo();
}
}
It might be the case that you do not want to do the generic stuff for Derived class. Then you would just remove the call to Base::foo().
Here you have a good reference on virtual methods.
It does call the base class method. Yes, the derived method is being called "polymorphically", but it can call its base method using Base::method
When qualified name (<class name>::<method name>) is used in a class method call, the method is called directly, non-virtually. In your example, baseClass::method is called. Since qualified name is used, the fact that the method is virtual means absolutely nothing and makes no difference whatsoever.
Related
I have an class:
class MyCoolBean {
public:
virtual void toot(){
log("ooh la la");
}
}
And my derived class:
class MyCoolBeansBoy : public MyCoolBean{
public:
void toot()override{
log("oh yeah");
}
}
If I do:
MyCoolBeansBoy boi;
boi.toot();
The output is:
oh yeah
But I want the output to be:
ooh la la
oh yeah
Now I know I can modify the derived function to be:
void toot()override{
MyCoolBean::toot();
log("oh yeah");
}
But if I do that, then anyone implementing a derived class can simply forget. Is there anyway to force MyCoolBean::toot() to be called ?
EDIT: I know this is technically possible because of this questions answers:
How to ensure that every method of a class calls some other method first?
The solution in the above link can be used to force calling a member function by all functions! My question is how to do it only for an overriden method, and call specifically the base method! :)
You don't.
(because it is not possible to do it reliably, the answer in your link is nice, but it only works with pointers which is quite a restriction)
Either you want the derived method to be the same as the one in the base, then you don't declare it as virtual, or...
If you want the derived classes to extend a base class methods functionality then you can use the so-called Template Method Pattern:
class MyCoolBean {
public:
void toot() { // <- not virtual !
log("ooh la la");
do_toot();
}
protected:
virtual void do_toot() {} // <- customization point
};
Derived class:
class MyCoolBeansBoy : public MyCoolBean{
private:
void do_toot() override {
log("oh yeah");
}
};
Now
MyCoolBeansBoy x;
x.toot();
will log both messages.
This achieves what you want but with somehow inverted logic: The base class "forces" each derived class to call a method of the derived class when a method from the base is called. do_toot could be pure virtual, then the derived class cannot forget to provide an implementation.
override keyword allows to make sure that the function will get overridden.
I am looking for the reverse functionality. So that - when I write a new function - I want to mark it with something to make sure it will not get accidentally overwritten.
(Also, I do not want to make it static, since it looks like to belong to an object rather than class)
I want to mark it with something to make sure it will not get accidentally overwritten.
You can use the final specifier. Example from cppreference:
struct Base
{
virtual void foo();
};
struct A : Base
{
void foo() final; // A::foo is overridden and it is the final override
void bar() final; // Error: non-virtual function cannot be overridden or be final
};
If you don't want a virtual function to be overridden in the derived class, you can use final:
Specifies that a virtual function cannot be overridden in a derived class or that a class cannot be inherited from.
e.g.
struct Base
{
virtual void foo() final; // foo cannot be overridden in the derived class
};
struct Derived : Base
{
void foo(); // Error: foo cannot be overridden as it's final in Base
};
final is the keyword you are looking for.
Remark: Be aware that override does not "make sure that the function will get overriden" as you put it. override in your derived class does make sure that you actually override a method of a base class, and not just introduce a new method that is similar to a virtual method of the base class.
To make sure that a method is overriden it would have to be pure virtual in your base class.
Also, static works exactly the other way round: static methods belong to the class, non-static methods need an object to be called.
How and when would I call a super class method? Please referr to code segment for the two options:
class SuperClass {
public:
void method();
};
class SubClass : public SuperClass {
public:
void someOtherMethdo(){
this->method();
SuperClass::method();
}
};
using this->method() you call a function that is either implemented in your superclass, either by your own class.
When using superClass::method(), you make sure to call the one implemented by your parent.
#include <iostream>
#include <string>
class A {
public:
void func() {
std::cout << "A func" << std::endl;
}
};
class B : A {
public:
void func() {
std::cout << "B func" << std::endl;
}
void exec() {
this->func();
A::func();
}
};
int main() {
B b;
b.exec();
return 0;
}
This sample code will output
B func
A func
this->method();
...calls method on the derived class (and is the same as writing simply method();). This could call the inherited method from the parent (and does in the example), or it could call an overridden version in the child class (and will, if one exists).
SuperClass::method();
...will always call the method on the parent. This syntax is often used within an override in the child, when you want to keep and extend the functionality of the parent class method. E.g.
Class SubClass: public SuperClass {
//...
void method() {
SuperClass::method();
//...
}
};
Note that if you use the first syntax in this second case, you'll get recursion.
Note also that this has nothing to do with virtual methods. Marking a method as virtual means that, when the method is called via a base class pointer, the most-derived class method available will be called. In the code above, it makes no difference whether any of the methods are virtual since there are no base class pointers involved.
this->method
Will default to the local implementation in your derived class first, if that one isn't present, it will take the superclass method. If that one is not present it will give a compilation error.
superClass::method()
Will always direct to the method in your superclass
In most cases you want this->method. superClass::method() Is usefull when part of a method is implemented in the superclass and you want to extend it in the derived class. something like:
Class SubClass : public SuperClass {
public:
void someOtherMethdo(){
SuperClass::someOtherMethdo();
//Rest of the method
}
}
this->method() leaves room for ambiguity under certain circumstances (e.g. if more than one ancestor defines method with this signature), but at the same time allows method to be called no matter where exactly it is defined. If method is virtual it will call the most-derived version.
SuperClass::method() is explicit. It will either call that specific method or give a compiler error.
In this particular example, no difference.
If the method is virtual:
this->method() will call the function dynamically (call the top-most implemented version of the class)
SuperClass::method() results in a static call.
this->method(); call parent's in your case or if it's virtual - call the top of implemented functions in vtable. SuperClass::method(); will call parent's method.
I have a base class MessageHandler and 2 derived classes, MessageHandler_CB and MessageHandler_DQ.
The derived classes redefine the handleMessage(...) method. MH_DQ processes a message and puts the result in a deque while MH_CB processes the message and then executes a callback function.
The base class has a static callback function that I pass along with a this pointer to a library which calls the static callback when a new message is available for processing.
My problem comes when I am in the static callback with a void * pointing to either a MH_DQ or a MH_CB. If I cast it to the base class the empty MessageHandler::handleMessage(...) method is called, rather than the version in the appropriate derived class.
What is the best way to address this situation from a design perspective and/or what language features might help me to implement a solution to my problem?
Thanks in advance!
Okay, the virtual method did not work like magic. There is a twist to the story. I have a static method in the base class and a pure virtual member function to handle the message processing, but I want to first call a member function in the pure virtual base class to preprocess the message before I route it to the derived class.
So I have :
class MH {
...
static int CallBackFunction(MessageData *md, void *this_ptr) {
((MH *)this_ptr)->preprocess(md);
return 1;
}
virtual int preprocess(MessageData *md) {
// do some stuff
. . .
handleMessage(md);
return 1;
}
virtual void handleMessage(MessageData *) = 0;
};
class MH_CB : public MH {
...
void handleMessage(MessageData *md) {
// do something
...
}
};
class MH_DQ : public MH {
...
void handleMessage(MessageData *md) {
// do something different
...
}
};
Unfortunately, this code produces a run-time error that a pure virtual function is being called. Any thoughts?
TIA
Make the original method call virtual.
Don't pass a void* in the callback - pass a pointer to the base class, and declare handleMessage to be virtual.
Add the virtual keyword to the declaration/definition of the method in the base class.
In fact if the method in the base class is never supposed to run then you can specify that it's pure virtual to declare it with no body at all, instead of defining an empty body:
class MessageHandler
{
public:
virtual void handleMessage(...) = 0;
};
Mark the handleMessage() as virtual by prefixing void handleMessage() or whatever declaration in the base class with the word virtual. Then, make sure that the derived classes implement the exact same message signature (i.e. same return type and parameter types).
Also- instead of a void* use a MessageHandlerBase* (or whatever is appropriate). Then you don't need to cast. Casting is often the sign of a logic error on the part of the programmer.
could anyone explain function overriding in c++ please! also am confused about virtual function concept. some tutorials say without the keyword virtual, both the derived class and base class objects invoke the base class function. then how does overriding take place?
There's no need to redocument what is already good and out there. I think this and this are a wonderful explanations about virtual functions. Then you probably also need to hear about abstract classes. Let us know if you have further questions.
Read this please. Concentrate on C++ sections. Then ask specific questions you have after reading.
Let me try to post an example (This is out of my head, so there may be slight syntax errors :) )
Baseclass:
class BaseClass
{
public:
void normalFunction();
virtual void virtualFunction();
}
Derived class:
class DerivedClass : public BaseClass
{
public:
void normalFunction();
virtual void virtualFunction();
}
Okay, so we got our classes defined. Now, some examples:
void main()
{
BaseClass base;
DerivedClass derived;
base.normalFunction(); //Invokes BaseClass::normalFunction();
base.virtualFunction(); //Invoked BaseClass::virtualFunction();
derived.normalFunction();//Invokes DerivedClass::normalFunction();
derived.virtualFunction();//Invokes DerivedClass::virtualFunction();
// Okay, nothing special yet, here comes the fun:
BaseClass *basePtr = &base;
BaseClass *derivedPtr = &derived;
basePtr->normalFunction(); //Invokes BaseClass::normalFunction();
basePtr->virtualFunction();//Invokes BaseClass::virtualFunction();
derivedPtr->normalFunction(); //Invokes BaseClass::normalFunction(); !! this is because it's a BaseClass pointer.
derivedPtr->virtualFunction();//Invokes DerivedClass::virtualFunction();
}
.. So, in conclusion, without virtual, the type of the pointer dictates which method will be invoked, with virtual, any type overriding the virtual method will have it's method called regardless of the pointer type :)
This is at a cose of a very minor overhead in the form of a vtable (virtual table), a compiler-detail which will map each method to the different derived types.
Each C++ class that has at least one virtual function contains a "virtual table" or VTABLE which is used to dynamically look up the address of a function at runtime.
Suppose you have two classes: Base and Derived. Further suppose that Derived derives from Base, and that "b" and "d" are instances of Derived, but b's compile-time type is Base and d's is Derived.
Now suppose that both Base and Derived declare a function "foo". Now, if "foo" is declared to be virtual in Base, then "foo" will have an entry in Base's VTABLE, and when you call "b.foo()" or "d.foo()", the compiler will know that it is a virtual function, and it will inject code that will look up the address of "foo" in the VTABLE at runtime.... which will find the address of the definition of "foo" as given in class Derived (i.e. Derived::foo).
Now suppose that both Base and Derived declare a function "foo", but "foo" has not been declared virtual in Base. When you call "b.foo()" or "d."foo()" the compiler will attempt to call Base::foo and Derived::foo directly, bypassing the virtual table lookup. Even though b's runtime type may be Derived, b's compile-time type is Base, and so calling "b.foo()" will result in "Base::foo" rather than "Derived::foo" being called.
In C++, the term "overriding" is used to refer to the former case; that is, when the function is declared as virtual, and another function in a derived class replaces the original function that was defined in the base class. By contrast, the term "overshadowing" is used to refer to the latter case; that is, a function in the derived class is called instead of the one in the base class, simply because it is closer in scope, but it has not truly replaced the function that was defined in the base class.
The override can only be done if you declare the function in the super virtual. Because it is virtual so it's not true ... meaning that is someone invoke it with that signature it may not invoke that function. We have to wait and see at runtime if someone overridden it. That is the meaning of virtual.
class A {
void F_A() { cout << "A' A"; }
virtual void F_B() { cout << "A' B"; }
}
class B : public A {
void F_B() { cout << "B' B"; }
}
A o = new B();
o.F_A(); // Non-virtual so the compiler knows that it can only be the one in class A
o.F_B(); // Virtual so the compiler does not know if at runtime ... o is instance of A or B. So it have to wait and see.
// In this case, it's B at runtime ('`new B()`'), so it run the one in B.
To sum up, if a function (method to be more precise) is declared 'virtual', it can be overridden. Otherwise, it can't be; hence, any invocation always goes to the one in the super class.
Hope this help clarifying.
For Virtual function always remember this thumb rule :
When function is normal then function
of type of object will be invoked,
When function is Virtual then function
of type of actual instance will be
called.
I like to illustrate this example with a Chess board;
class ChessPiece
{
public:
void moveTo(Pos dst);
virtual checkValidAndMoveTo(Pos dst) = 0;
};
class King: public ChessPieve
{ virtual checkValidAndMoveTo(Pos dst);}
class Queen: public ChessPieve
{ virtual checkValidAndMoveTo(Pos dst);}
// etc
ChessPiece* board[8][8];
So when a move is made to square the game will call checkValidAndMoveTo() on the piece.
board[pickedUpPiece.x][pickedUpPiece.y]->checkValidAndMoveTo()
This will now call the appropriate checkValidAndMoveTo() for the particular piece. Once this move is finished we expect it to call MoveTo(). Since at the point it knows what type is is it will drill to down and get the most overidden version of MoveTo() below it current type.