I am experiencing a problem where a derived class does not have it's own version of a function called when it is called from a base class pointer. To better explain the classes are defined as below
Class Foo
{
public:
Foo();
virtual ~Foo();
virtual void Event();
}
//-----------------------
Class FooBar : public Foo
{
public:
FooBar();
virtual void Update() = 0;
virtual void Draw() = 0;
}
//-----------------------
Class FinalFoo : public FooBar
{
public:
FinalFoo();
void Update();
void Draw();
void Event();
}
There are other classes similar to FinalFoo. So I attempt to call Event on a pointer to a Foo object expecting that it would call the derived implementation. However, it would appear that it calls the base class version and that is all
FinalFoo* myThing = new FinalFoo();
Foo* baseThing = myThing;
baseThing->Event(); // I expected this to call FinalFoo::Event()
Assuming the above code is corrected, it actually does call FinalFoo::Event(). below is a complete and compilable example. Note, that it also adds the keyword override in strategic points: I'd bet that adding override in the original code, too (and compiling with a compiler aware of this keyword) would point out that your override isn't one.
#include <iostream>
class Foo
{
public:
virtual ~Foo() {}
virtual void Event() { std::cout << "Foo::Event()\n"; }
};
//-----------------------
class FooBar : public Foo
{
public:
virtual void Update() = 0;
};
//-----------------------
class FinalFoo : public FooBar
{
public:
FinalFoo() {}
void Update() override { std::cout << "FinalFoo::Update()\n"; }
void Event() override { std::cout << "FinalFoo::Event()\n"; }
};
int main()
{
FinalFoo myThing;
Foo* baseThing = &myThing;
baseThing->Event();
}
Related
This code demonstrates the problem:
class Base
{
public:
explicit Base(std::function<void()> const& printFunc) :
_printFunc(printFunc)
{
}
void print()
{
_printFunc();
}
private:
std::function<void()> _printFunc{};
private:
virtual void _print() = 0; // If this line is commented out, then
// `Subclass1::_print()` can be called.
};
class Subclass1 : public Base
{
public:
explicit Subclass1() :
Base([this]() { _print(); })
{
}
private:
void _print() /*override*/
{
std::cout << "Subclass1\n";
}
};
class Subclass2 : public Base, public Subclass1
{
public:
using fromLowestSubclass = Base;
public:
explicit Subclass2() :
Base([this]() { _print(); }), Subclass1()
{
}
private:
void _print() /*override*/
{
// Here is the problem:
Subclass1::print(); // or: static_cast<Subclass1*>(this)->print();
std::cout << "Subclass2\n";
}
};
int main()
{
Subclass2 sc2{};
sc2.fromLowestSubclass::print();
return 0;
}
In the Subclass2::_print method, the overriding _print method of Subclass1 should be called, but instead the Subclass1::print(); statement calls the current method again. This problem can be prevented if the statement virtual void _print() = 0; is commented out.
Why use of the virtual _print method prevents me from invoking the overloaded virtual method Subclass1::_print and what solution is there so that I do not have to do without virtual methods?
class Base
{
....
private:
virtual void _print() = 0;
}
This means: you can override _print, but you can't call it, only Base has right to call it.
Now:
class Base
{
public:
void print()
{
_printFunc();
}
does that, it calls _printFunc as a virtual function, which matches current object instantiation. It doesn't meter how print() was invoked.
Adding Subclass1:: as a prefix just changes name scope and doesn't have impact how method behaves. It has only have impact on name scope.
Now if virtual method has such prefix, then selecting name scope instruct compiler that you abandoning abstraction and you need to call specific method. In such case method is called without referring to a virtual table.
Double inheritance has no impact on this issue.
You can provide a helper method which you will be able to call from ancestor:
class Subclass1 : public Base
{
....
protected:
void sub1_print() // not virtual
{
std::cout << "Subclass1\n";
}
private:
void _print() /*override*/
{
sub1_print();
}
};
class Subclass2 : public Base, public Subclass1
{
....
private:
void _print() /*override*/
{
sub1_print();
std::cout << "Subclass2\n";
}
};
I'm looking for ways to avoid the "call super" code smell. This code smell is present when a subclass is required to invoke the super class's version of a virtual function when re-implementing that function.
class Base
{
public:
virtual void foo(){ ... }
}
class Derived : public Base
{
public:
virtual void foo(){ Base::foo();// required! ... }
}
If inheritance went only a single layer deep, I could use the template method
class Base
{
public:
void foo(){ ... ; foo_impl(); }
protected:
virtual void foo_impl(){}
}
class Derived : public Base
{
protected:
virtual void foo_impl(){ ... }
}
But if I need to subclass Derived, I'm back where I started.
I'm considering a registration approach.
class Base
{
public:
Base()
{
_registerCallback( [this](){ _baseFoo(); } );
}
void foo()
{
for( auto f : _callbacks )
f();
}
protected:
void registerCallback( std::function<void()> f )
{
_callbacks << f;
}
private:
void _baseFoo() { ... }
std::list< std::function<void()> > _callbacks;
}
class Derived : public Base
{
public:
Derived()
{
_registerCallback( [this](){ _derivedFoo(); } );
}
private:
virtual void _derivedFoo(){ ... }
}
Is there a more standard approach? Any problems with or improvements to this approach?
Use of
class Derived : public Base
{
public:
virtual void foo(){ Base::foo();// required! ... }
}
is the best approach IMO. I am not sure why you would consider that "code smell".
The potential for error is higher in the last approach you suggested.
It's easier to detect a missed call to Base::foo().
If all the classed derived from Base need to implement what Base::foo() does, it's better that the common code be in Base::foo(). The derived classes simply need to make the call.
For what it's worth, we use the pattern at my work a lot and it has proven to be robust over 20+ years of usage.
You can continue using template methods all the way down if you introduce new virtual member function on each level and override it on next one:
template <typename> struct tag {};
class Base
{
public:
void foo() { ... ; foo_impl(tag<Base>{}); }
protected:
virtual void foo_impl(tag<Base>) {}
};
class Derived1 : public Base
{
protected:
virtual void foo_impl(tag<Base>) override final { ... ; foo_impl(tag<Derived1>{}); }
virtual void foo_impl(tag<Derived1>) {}
};
class Derived2 : public Derived1
{
protected:
virtual void foo_impl(tag<Derived1>) override final { ... ; foo_impl(tag<Derived2>{}); }
virtual void foo_impl(tag<Derived2>) {}
};
class Derived3 : public Derived2
{
protected:
virtual void foo_impl(tag<Derived2>) override final { ... ; foo_impl(tag<Derived3>{}); }
virtual void foo_impl(tag<Derived3>) {}
};
If you dislike tag dispatch you can just give methods different names instead, perhaps something like foo_impl_N.
I consider all this overengineering.
chris mentioned a primary concern regards childs not calling their parent's corresponding member functions, this gives an idea about fixing that part:
#include <cassert>
class Base {
public:
void foo() {
foo_impl();
assert(base_foo_called && "call base class foo_impl");
}
protected:
virtual void foo_impl() { base_foo_called = true; }
private:
bool base_foo_called = false;
};
class DerivedFine : public Base {
protected:
void foo_impl() override {
Base::foo_impl();
}
};
class DerivedDerivedFine : public DerivedFine {
protected:
void foo_impl() override {
DerivedFine::foo_impl();
}
};
class DerivedDerivedNotFine : public DerivedFine {
protected:
void foo_impl() override {}
};
int main() {
DerivedFine foo;
foo.foo();
DerivedDerivedFine bar;
bar.foo();
DerivedDerivedNotFine baz;
baz.foo(); // this asserts
}
CRTP can solve everything.
For each foo method, you implement an empty non-virtual foo_before() that does nothing in your CRTP helper.
CRTP helper takes a derived and a base. Its virtual void foo() invokes static_cast<Derived*>(this)->foo_before() then Base::foo() then after_foo().
struct Base {
virtual void foo() { std::cout << "foo\n"; }
virtual ~Base() {};
};
template<class D, class B=Base>
struct foo_helper:B {
virtual void foo() {
static_cast<D*>(this)->before_foo();
this->B::foo();
static_cast<D*>(this)->after_foo();
}
private:
void before_foo() {}; void after_foo() {};
};
struct Derived1 : foo_helper<Derived1> {
void before_foo() { std::cout << "before1\n"; }
};
struct Derived2 : foo_helper<Derived2> {
void before_foo() { std::cout << "before2\n"; }
void after_foo() { std::cout << "after2\n"; }
};
struct DoubleDerived : foo_helper<DoubleDerived, Derived2> {
void after_foo() { std::cout << "even more after\n"; }
};
int main() {
std::cout << "---- Derived1\n";
Derived1 d1;
d1.foo();
std::cout << "---- Derived2\n";
Derived2 d2;
d2.foo();
std::cout << "---- DoubleDerived\n";
DoubleDerived dd;
dd.foo();
}
Live example.
Output:
---- Derived1
before1
foo
---- Derived2
before2
foo
after2
---- DoubleDerived
before2
foo
after2
even more after
Here's an idea inspired by this answer
The idea is to use the fact that constructors and destructors of a struct / class provides a sort of "pre/post function calling" mechanism that gets inherited. So instead of doing the pre/post function calls in the virtual method itself, we can use a functor and define the pre/post function call in the constructor / destructor. That way, functors that inherit from the base functor will inherit the pre/post function call.
Code
struct BasePrePostFunctor
{
BasePrePostFunctor()
{
printf("Base pre-func\n");
}
virtual void operator()()
{
printf("Base Main func\n");
}
~BasePrePostFunctor()
{
printf("Base post-func\n");
}
};
struct DerivedPrePostFunctor : BasePrePostFunctor
{
DerivedPrePostFunctor()
{
printf("Derived pre-func\n");
}
void operator()() override
{
printf("Derived main func\n");
}
~DerivedPrePostFunctor()
{
printf("Derived post-func\n");
}
};
class BaseClass
{
public:
virtual void virtual_func()
{
BasePrePostFunctor func;
func();
}
};
class DerivedClass : public BaseClass
{
public:
void virtual_func() override
{
DerivedPrePostFunctor func;
func();
}
};
int main(int argc, char** argv)
{
DerivedClass derived;
derived.virtual_func();
};
Output
Base pre-func
Derived pre-func
Derived main func
Derived post-func
Base post-func
So I have two classes. One has only purely virtual functions. THe other implements those functions and is derived from the first class.
I get that i cant instantiate the first class. But when I try to create an object of the second class it fails as well.
This is how my second class looks in general:
class SecondClass : public FirstClass
{
public:
SecondClass();
virtual ~SecondClass(void);
void Foo();
void Bar();
}
Implementation:
SecondClass::SecondClass()
{...}
SecondClass::~SecondClass(void)
{...}
void SecondClass::Foo()
{...}
void SecondClass::Bar()
{...}
This how I instantiate it and get the Error:
SecondClass mSecClass;
Where am I going wrong here?
FirstClass.h
class FirstClass
{
public:
FirstClass(void);
virtual ~FirstClass(void);
virtual void Foo() = 0;
virtual void Bar() = 0;
};
You need to define the ~FirstClass() destructor and leave out its constructor
class FirstClass
{
public:
virtual ~FirstClass(void) {} // or use C++11 = default syntax
virtual void Foo() = 0;
virtual void Bar() = 0;
};
class SecondClass : public FirstClass
{
public:
SecondClass();
virtual ~SecondClass(void);
void Foo();
void Bar();
};
SecondClass::SecondClass() {}
SecondClass::~SecondClass(void) {}
void SecondClass::Foo() {}
void SecondClass::Bar() {}
int main()
{
SecondClass mSecClass;
}
Live Example.
Define every function you declare, except for pure virtuals(virtual void foo() = 0).
try the below code:
#include<iostream>
using namespace std;
class FirstClass
{
public:
FirstClass()
{
//
}
virtual ~FirstClass();
virtual void Foo();
virtual void Bar();
};
FirstClass::~FirstClass()
{
//
}
void FirstClass::Foo()
{
//
}
void FirstClass::Bar()
{
//
}
class SecondClass : public FirstClass
{
public:
SecondClass();
virtual ~SecondClass(void);
void Foo();
void Bar();
};
SecondClass::SecondClass(){
//
}
SecondClass::~SecondClass(void)
{//
}
void SecondClass::Foo()
{//
}
void SecondClass::Bar()
{//
}
int main()
{
SecondClass name;
return 0;
}
Is it possible to have a derived class to have two sets of the same virtual functions as the base class? I'm looking to do something like the following. The idea being able to choose between two sets of function pointers.
class Base
{
virtual void func1;
virtual void func2;
};
class Derived: Base
{
float somemember;
void somefunction()
{
Base* func = this->derived_functions1;
}
class derived_functions1
{
virtual void func1()
{
return somemember*100;
}
virtual void func2;
};
class derived_functions2
{
virtual void func1;
virtual void func2;
};
};
class Base
{
public:
virtual void func1();
virtual ~Base(){}
};
struct Impl1 : Base
{
void func1() override {}
};
struct Impl2 : Base
{
void func1() override {}
};
struct Derived : Base
{
Derived(std::unique_ptr<Base> implementation) :
impl(std::move(implementation))
{}
void func1() override { impl->func1(); }
void changeImpl(std::unique_ptr<Base> implementation)
{
impl = std::move(implementation);
}
private:
std::unique_ptr<Base> impl;
};
Not the way you did. But you can make both the inner class derived_functionsX to be themseves public: Base, than have your main Derived to contain a std::unique_ptr<Base> ptryou can set to new derived_functions1 or new derived_functions2
and implement in Derived func1 and func2 to call ptr->func1() and ptr->func2().
For all that to work properly, Base must also have a virtual ~Base() {} otherwise no proper deletion can be done.
In this example, it won't compile, since derived_function1 and derived_functions2 aren't inheriting from Base.
But you could have something like this:
class Base
{
virtual void func1();
virtual void func2();
};
class Wrapper {
public:
Wrapper(int arg)
{
switch(arg)
{
case 1:
b = new derived_functions1;
break;
case 2:
b = new derived_functions2;
break;
default:
cout << "bad value of arg" << arg << endl;
exit(1);
}
}
~Wrapper()
{
delete b;
}
Base* GetClass()
{
return b;
}
private:
Base *b;
class derived_functions1: public Base
{
virtual void func1();
virtual void func2();
};
class derived_functions2: public Base
{
virtual void func1();
virtual void func2();
};
};
Short answer: No. A class can override inherited virtual functions only once.
However, there is a design pattern that exchanges function's behavior on the fly, called Strategy Pattern. In short: the class that has exchangeable behavior has a pointer to a Strategy base class that defines the interface for that behavior. It is populated with concrete Strategy classes. The function that has different behavior just delegates its calls to the Strategy pointer. Here's an example, tailored to your question:
class Base {
public:
virtual void func1() = 0;
virtual void func2() = 0;
virtual ~Base(){}
};
#include <iostream>
#include <memory>
class Derived : public Base
{
struct F1Strategy {
virtual void f1Impl() = 0;
virtual ~F1Strategy() {}
};
struct Impl1 : F1Strategy {
void f1Impl() override { std::cout << "one!\n"; }
};
struct Impl2 : F1Strategy {
void f1Impl() override { std::cout << "two?\n"; }
};
std::unique_ptr<F1Strategy> f1Strategy;
public:
Derived()
: f1Strategy(new Impl1())
{}
void func1() override { f1Strategy->f1Impl(); }
void func2() override {
static std::unique_ptr<F1Strategy> otherStrategy(new Impl2());
f1Strategy.swap(otherStrategy);
}
};
int main() {
std::unique_ptr<Base> pb(new Derived());
pb->func1(); // ==> one!
pb->func2(); //swap
pb->func1(); // ==> two?
pb->func1(); // ==> two?
pb->func2(); //swap
pb->func1(); // ==> one!
}
See it in action: http://ideone.com/zk3UTI
Why is it that in the code below the compiler complains that PureAbstractBase is an ambiguous base class of MultiplyInheritedClass? I realize I have two copies of the PureAbstractBase in MultiplyInheritedClass and that FirstConreteClass and SecondConreteClass should be derived virtually because they're the middle row of the diamond (and that does indeed fix the problem with the code below). But even though I have two copies of the interface why is it that the code in MultiplyInheritedClass does not just override both and unambiguously pick the interface class defined in MultiplyInheritedClass?
#include <iostream>
using namespace std;
class PureAbstractBase {
public:
virtual void interface() = 0;
};
// I know that changing the following line to:
// class FirstConcreteClass : public virtual PureAbstractBase {
// fixes the problem with this hierarchy
class FirstConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { cout << "This is object FirstConcreteClass\n"; }
};
// I know that changing the following line to:
// class SecondConcreteClass : public virtual PureAbstractBase {
// fixes the problem with this hierarchy
class SecondConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { cout << "This is object SecondConcreteClass\n"; }
};
class MultiplyInheritedClass : public FirstConcreteClass,
public SecondConcreteClass {
public:
virtual void interface() { implementation(); }
private:
void implementation() { cout << "This is object MultiplyInheritedClass\n"; }
};
Further, why do I not have issues with the following hierarchy? Doesn't the ConcreteHandler class have three copies of the AbstractTaggingInterface in this case? So why doesn't it have the same issue as the example above?
#include <iostream>
using namespace std;
class AbstractTaggingInterface {
public:
virtual void taggingInterface() = 0;
};
class FirstAbstractHandler : public AbstractTaggingInterface {
public:
virtual void taggingInterface() { cout << "FirstAbstractHandler\n"; }
virtual void handleFirst() = 0;
};
class SecondAbstractHandler : public AbstractTaggingInterface {
public:
virtual void taggingInterface() { cout << "SecondAbstractHandler\n"; }
virtual void handleSecond() = 0;
};
class ThirdAbstractHandler : public AbstractTaggingInterface {
public:
virtual void taggingInterface() { cout << "ThridAbstractHandler\n"; }
virtual void handleThird() = 0;
};
class ConcreteHandler : public FirstAbstractHandler,
public SecondAbstractHandler,
public ThirdAbstractHandler {
public:
virtual void taggingInterface() = { cout << "ConcreteHandler\n"; }
virtual void handleFirst() {}
virtual void handleSecond() {}
virtual void handleThird() {}
};
I am trying to wrap my head around all of this because I had a conversation with a colleague recently where he claimed that if you were inheriting from pure virtual classes (interfaces) without any data members then virtual inheritance was not necessary. I think understanding why the former code example does not work and the latter does would go a long way to getting this straight in my head (and clear up what exactly he meant by his comment). Thanks in advance.
You need virtual inheritance to overcome the diamond-ambiguity:
class FirstConcreteClass : public virtual PureAbstractBase { ... };
class SecondConcreteClass : public virtual PureAbstractBase { ... };
Long-winded explanation: Suppose you have this:
// *** Example with errrors! *** //
struct A { virtual int foo(); };
struct B1 : public A { virtual int foo(); };
struct B2 : public A { virtual int foo(); };
struct C: public B1, public B2 { /* ... */ }; // ambiguous base class A!
int main() {
A * px = new C; // error, ambiguous base!
px->foo(); // error, ambiguous override!
}
The inheritance of the virtual function foo is ambiguous because it comes in three ways: from B1, from B2 and from A. The inheritance diagram forms a "diamond":
/-> B1 >-\
A-> ->C
\-> B2 >-/
By making the inheritance virtual, struct B1 : public virtual A; etc., you allow any baseclass of C* to call the correct member:
struct A { virtual int foo(); };
struct B1 : public virtual A { virtual int foo(); };
struct B2 : public virtual A { virtual int foo(); };
struct C: public B1, public B2 { virtual int foo(); };
We must also define C::foo() for this to make sense, as otherwise C would not have a well-defined member foo.
Some more details: Suppose we now have a properly virtually-inheriting class C as above. We can access all the various virtual members as desired:
int main() {
A * pa = new C;
pa->foo(); // the most derived one
pa->A::foo(); // the original A's foo
B1 * pb1 = new C;
pb1->foo(); // the most derived one
pb1->A::foo(); // A's foo
pb1->B1::foo(); // B1's foo
C * pc = new C;
pc->foo(); // the most derived one
pc->A::foo(); // A's foo
pc->B1::foo(); // B1's foo
pc->B2::foo(); // B2's foo
pc->C::foo(); // C's foo, same as "pc->foo()"
}
Update: As David says in the comment, the important point here is that the intermediate classes B1 and B2 inherit virtually so that further classes (in this case C) can inherit from them while simultaneously keeping the inheritance from A unambiguous. Sorry for the initial mistake and thanks for the correction!
Your first example fails because the compiler cannot disambiguate between the three implementations of implementation(). You are overriding that method in MultiplyInheritedClass, which actually overrides both FirstConcreteClass::implementation and SecondConcreteClass::implementation (once virtual, always virtual). However, both virtual calls still exist in the interface of MultiplyInheritedClass, which makes the call ambiguous at the call site.
The reason that your example works without virtual inheritance is that there is no conflicting implementation of the common base class. Put another way:
class Base
{
public:
void DoSomething() {
std::cout << "TADA!";
}
}
class One : public Base
{
//...
}
class Two : public Base
{
//...
}
class Mixed : public One, public Two
{
//...
}
int main()
{
Mixed abc;
abc.DoSomething(); //Fails because the compiler doesn't know whether to call
// One::DoSomething or Two::DoSomething, because they both
// have implementations.
//In response to comment:
abc.One::DoSomething(); //Succeeds! You removed the ambiguity.
}
Because your example has all pure virtual functions, there's no multiple implementations which the compiler needs to disambiguate. Therefore, only one implementation exists, and the call is unambiguous.
I tried both of the question codes and they worked fine when instantiating an object of the multi-inherited class. It didn't work only with polymorphism, like this for example:
PureAbstractBase* F;
F = new MultiplyInheritedClass();
And the reason is clear: it doesn't know to which copy of the Abstract base class it should be linked (sorry for bad expressions, I understand the idea but can't express it). And since inherting virtaully makes only one copy exist in the derived class, then it's fine.
Also the code of Billy ONeal is not clear at all, what should we place instead of the comments?
If we place:
public:
void DoSomething()
{ std::cout << "TADA!"; }
it works fine, because of no virtuality.
I work on Visual Studio 2008.
Why not do it like this (suggested in Benjamin Supnik's blog entry):
#include <iostream>
class PureAbstractBase {
public:
virtual void interface() = 0;
};
class FirstConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { std::cout << "Fisrt" << std::endl; }
};
class SecondConcreteClass : public PureAbstractBase {
public:
virtual void interface() { implementation(); }
private:
void implementation() { std::cout << "Second" << std::endl; }
};
class MultiplyInheritedClass : public FirstConcreteClass,
public SecondConcreteClass
{
public:
virtual void interface() { implementation(); }
private:
void implementation() { std::cout << "Multiple" << std::endl; }
};
int main() {
MultiplyInheritedClass mic;
mic.interface();
FirstConcreteClass *fc = &mic; //disambiguate to FirstConcreteClass
PureAbstractBase *pab1 = fc;
pab1->interface();
SecondConcreteClass *sc = &mic; //disambiguate to SecondConcreteClass
PureAbstractBase *pab2 = sc;
pab2->interface();
}
which gives:
Multiple
Multiple
Multiple
This way:
no virtual bases are involved (do you really need them?)
you can call the overriden function via a an instance of the MultiplyInheritedClass
ambiguity is removed by a two-stage conversion