So let us say I have some chain of classes where each class is derived from the class before it. For whatever reason, they all like to use the same name for some member function. Kinda like this:
class C1 { public: void f() { cout<<"C1"; }; };
class C2 : public C1 { public: void f() { cout<<"C2"; }; };
class C3 : public C2 { public: void f() { cout<<"C3"; }; };
Obviously, if I just declare some objects, then call the function f from them, all will call the function associated with their respective object-type:
C1 c1; c1.f(); // prints C1
C2 c2; c2.f(); // prints C2
C3 c3; c3.f(); // prints C3
Now, if I declare some pointers-to-objects, then call the function f from them, all will call the function associated with their respective pointer-type:
C1* p1 = &c1; p1->f(); // prints C1
C1* p2 = &c2; p2->f(); // prints C1
C1* p3 = &c3; p3->f(); // prints C1
C2* p4 = &c2; p4->f(); // prints C2
C2* p5 = &c3; p5->f(); // prints C2
C3* p6 = &c3; p6->f(); // prints C3
All of this is super. I either call the function associated with the object's type or I call the function associated with the pointer's type...
Or of course I could make the function 'virtual'. Then if I call the function from some object, I will get no change in behavior; however, if I call the function from some pointer, then I won't just call the function for the pointer's type, I will actually call the function for the object-type that the pointer is pointing to. So far so good.
I can even make the change to virtual mid-way through the chain of inheritance. Let's say I put a virtual before the function f inside of class C2. Now the function has been made virtual (i.e. when called from pointers, it uses the object-pointed-to-type instead of the pointer-type to resolve the function call), not only for its own class, but for all future classes that are derived from it.
My question is this: Once a function has been declared virtual (at some point in the chain of inheritance) can it ever be reverted back to being non-virtual (further down the chain of inheritance)?
For clarification: When I say revert back to non-virtual behavior, I mean that when I call the function from a pointer, it will use the pointer's type to resolve the function call (and not the object-type that the pointer is pointing to).
Once a function has been declared virtual (at some point in the chain of inheritance) can it ever be reverted back to being non-virtual (further down the chain of inheritance)?
No. Once a function signature has been made virtual
somewhere along the line of inheritance, it will stay that way: every function with the same signature in a derived class will be virtual
as well.
One way to get around this is to use (abuse?) the template method pattern:
struct Base {
virtual void doFoo() { bar(); }
void foo() { doFoo(); }
};
struct Derived1 : public Base {
virtual void doFoo() { baz(); } // "overrides" foo via doFoo
};
struct Derived2 : public Base {
void foo() { quux(); } // "un-virtualize" foo by decoupling it from doFoo
};
In this inheritance tree, the pointer type will determine which foo
is called; if it's the one from Base
, the pointed-to object's type will determine which doFoo
is called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With