Hello,

I've confused myself a bit with virtual functions. I know they're useful when you want to call the parents function via casting the class to it's parent, but I've found myself scratching my head on few cases.

So... Lets say I have a parent Class P and a child class C. P has a function setupBuffer() and is called by the constructor. I want the child class to overide it such that when the parent calls setupBuffer() it calls the child's version. Should either be virtual?

Another situation is when I want the child class always to be called even if casted as the parent.

In what cases would doing:

void c::func()
{
p::func();
}
not work, or will it always work regardless of virtual being tagged to function?

What's the difference between having the parent func being virtual and when both are virtual? Also, if the child was only virtual, would that do anything (in relationship to the parent)?

I want the child class to overide it such that when the parent calls setupBuffer() it calls the child's version. Should either be virtual?

If you're overriding a parent class member function's behavior in a child class, it should probably be virtual.

Another situation is when I want the child class always to be called even if casted as the parent.

Provided the actual object is a child, that's exactly what polymorphism does. Note that this only applies through either a pointer or a reference. If you're taking a child object and casting it to parent, then dynamic binding doesn't take place and the parent member functions will be called.

What's the difference between having the parent func being virtual and when both are virtual?

Virtuality is inherited, so if the parent member function is virtual, the child member function is implicitly virtual.

Also, if the child was only virtual, would that do anything (in relationship to the parent)?

If the parent member function is not virtual and the child defines an exact copy that's virtual, the child's member function replaces the parent's version and things can get sticky due to the multiple copies.

#include <iostream>

using namespace std;

class parent {
public:
    virtual void a() { cout << "parent::a\n"; }
    void b() { cout << "parent::b\n"; }
};

class child: public parent {
public:
    void a() { cout << "child::a\n"; }
    virtual void b() { cout << "child::b\n"; }
};

class grandchild: public child {
    void a() { cout << "grandchild::a\n"; }
    void b() { cout << "grandchild::b\n"; }
};

int main()
{
    parent *a = new parent;
    parent *b = new child;
    parent *c = new grandchild;
    
    a->a();
    a->b();
    
    b->a();
    b->b();
    
    c->a();
    c->b();

    child d;
    
    ((parent)d).a();
    ((parent)d).b();
}

Edited 5 Years Ago by Narue: thinking in another language for a moment. ;p

P has a function setupBuffer() and is called by the constructor. I want the child class to overide it such that when the parent calls setupBuffer() it calls the child's version. Should either be virtual?

No. You cannot achieve this, whether your function is virtual or not. You cannot safely call a virtual function from a parent-class constructor and expect it to call the function from the child-class. The virtual dispatch mechanism is not put in place until the object is fully constructed. You can call other non-virtual functions without fear, you can even call virtual functions, but it won't be the child-class version of the function that will be called, it will be the parent-class version, if it exists.

Anyways, just don't do that, find another way.

Another situation is when I want the child class always to be called even if casted as the parent.

By "casted" if you mean that you cast a reference or pointer to a child-class object into a reference or pointer to a parent-class object, then, yes, that is exactly what virtual functions are for, and this "substitutability" of a child-class pointer (or reference) where a parent-class pointer (or reference) is needed is called "polymorphism".

In what cases would doing:

void c::func()
{
p::func();
}
not work, or will it always work regardless of virtual being tagged to function?

This will always work, regardless of the "tags" on the functions. The difference is not within the implementation of the class, but which functions get called from outside the class. In either case (virtual or not), when writing p::func(), you will call the version of the function that is implemented in the parent class. The difference between virtual or not is whether the child version of func() will be called in the first place or not.

What's the difference between having the parent func being virtual and when both are virtual?

No difference at all. When a function is virtual in the parent-class, it is implicitly virtual in the child-class.

Also, if the child was only virtual, would that do anything (in relationship to the parent)?

If the function is not marked virtual in the parent-class but is marked virtual in the child-class, with respect to the relationship of parent and child, there is no difference between that and having both functions non-virtual. When a parent-class and a child-class have the same function (same name), then the parent-class functions will be hidden. This means that if you have an object of the child-class, you won't be able to call the function version from the parent-class unless you make a pointer or reference cast to the parent-class. And, in that case also, calling the function using a parent-class pointer or reference to the child-class object will not call the child-class version of the function, but will call the parent-class version.


Nota Bene: Typical terminology used in C++ is not "parent class" "child class" but usually "base class" "derived class".

Also, you should read this FAQ page.

This article has been dead for over six months. Start a new discussion instead.