Why exactly doesn't this work? Are the inherited function signatures subtly incorrect or is the abstract base class enforced "before" the member functions are inherited or is it something else? Could this be convinced to work without function wrappers?
#include <iostream>
struct AbsBase {
virtual void foo() = 0;
virtual void bar() = 0;
};
struct ProvideFoo {
void foo() { std::cout << "foo\n"; }
};
struct ProvideBar {
void bar() { std::cout << "bar\n"; }
};
struct Concrete : public ProvideFoo, public ProvideBar, public AbsBase {
// I guess I could put function wrappers here... sigh...
//void bar() {ProvideBar::bar();}
//void foo() {ProvideFoo::foo();}
};
int main() {
Concrete c;
c.foo();
c.bar();
}
I think the downvoters are a bit harsh on you, as your reasoning to supply the implementations of the two pure virtual functions through separate classes has some intuitive appeal.
Alas, you are doing two unrelated things at the same time. ProvideFoo
and ProvideBar
are completly unrelated to the AbsBase
abstract class. You could also subclass both of them from AbsBase
, but then each of them would still be an abstract class. In either case, your current Concrete
is an abstract class because it derives from at least one class with a pure virtual function. You can't create objects from such classes.
The easiest way is to drop subclassing from AbsBase
altogether and subclass from ProvideFoo
and ProvideBar
directly. Of course, now you don't have virtual
functions inside Concrete
, so further subclassing can't easily override foo
and bar
functionality.
#include <iostream>
struct ProvideFoo {
void foo() { std::cout << "foo\n"; }
};
struct ProvideBar {
void bar() { std::cout << "bar\n"; }
};
struct Concrete : public ProvideFoo, public ProvideBar {};
int main() {
Concrete c;
c.foo();
c.bar();
}
Live Example I
You can also create multiple interfaces and multiple concrete implementations, something like this:
#include <iostream>
struct AbsFoo {
virtual void foo() = 0;
};
struct AbsBar {
virtual void bar() = 0;
};
struct ProvideFoo: AbsFoo {
void foo() { std::cout << "foo\n"; }
};
struct ProvideBar: AbsBar {
void bar() { std::cout << "bar\n"; }
};
struct Concrete : public ProvideFoo, public ProvideBar {};
int main() {
Concrete c;
c.foo();
c.bar();
}
Live Example II
Now for the encore: you can also use virtual
inheritance when subclassing ProvideFoo
and ProvideBar
from AbsBase
by using the virtual
keyword
#include <iostream>
struct AbsBase {
virtual void foo() = 0;
virtual void bar() = 0;
};
struct ProvideFoo: virtual AbsBase {
void foo() { std::cout << "foo\n"; }
};
struct ProvideBar: virtual AbsBase {
void bar() { std::cout << "bar\n"; }
};
struct Concrete : public ProvideFoo, public ProvideBar {};
int main() {
Concrete c;
c.foo();
c.bar();
}
This is really advanced C++ and can become really complicated if your classes also contain member data. I would prefer to use the 2nd solution for your code.
Live Example III
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