I'm getting a compile error when I try to compile my code.
The error is this:
multi.cc: In function ‘int main()’:
multi.cc:35: error: cannot declare variable ‘mdc’ to be of abstract type ‘MostDerivedClass’
multi.cc:27: note: because the following virtual functions are pure within ‘MostDerivedClass’:
multi.cc:13: note: virtual int Interface2::common_func()
multi.cc:36: error: request for member ‘common_func’ is ambiguous
multi.cc:13: error: candidates are: virtual int Interface2::common_func()
multi.cc:21: error: virtual int InterimClass::common_func()
And here is my code:
class Interface1 {
public:
virtual int common_func() = 0;
virtual ~Interface1() {};
};
class Interface2 {
public:
virtual int common_func() = 0;
virtual int new_func() = 0;
virtual ~Interface2() {};
};
class InterimClass : public Interface1 {
public:
virtual int common_func() {
return 10;
}
};
class MostDerivedClass : public InterimClass, public Interface2 {
public:
virtual int new_func() {
return 20;
}
};
int main() {
MostDerivedClass mdc;
int x = mdc.common_func();
cout << "The value = " << x << endl;
Interface2 &subset_of_funcs = dynamic_cast<Interface2 &>(mdc);
x = subset_of_funcs.common_func();
}
My questions:
How do I tell the compiler that common_func() is already implemented by the InterimClass which is a base class of MostDerivedClass?
Is there another way to fix my problem? What I would really like to do is to be able to also call common_func from Interface2. I'm working with some legacy code with a huge amount of methods in Interface1. In my new code, I only want to call a small set of these Interface1 functions, plus a few that I need to add.
You need to define a common_func() anyway in MostDerivedClass to satisfy your inheritance from Interface2
you can try something like
virtual int common_func() {
return InterimClass::common_func();
}
This is most useful if you cannot change the first Interface1
If you want a real inheritance relationship between your classes you need to follow Lol4t0 advice. Extract a superclass from Interface1, and make Interface2 subclass of this newly created class. Example :
class RootInterface{
public :
virtual int common_func() = 0;
virtual ~RootInterface(){}
};
class Interface1 : public virtual RootInterface{
public:
virtual ~Interface1() {};
};
class Interface2 : public virtual RootInterface{
public:
virtual int new_func() = 0;
virtual ~Interface2() {};
};
class InterimClass : public Interface1 {
public:
virtual int common_func() {
return 10;
}
};
class MostDerivedClass : public InterimClass, public Interface2 {
public:
virtual int new_func() {
return 20;
}
};
Add an override in MostDerivedClass, and from it call InterimClass::common_func().
First of all, I don't really understand the sense of your code.
You need to know that only Interface1::common_func is implemented.
Why don't you make Interface2 inherit from Interface1? I guess you want for both common_func methods to be equal.
Example code (uses polymorphism):
class Interface1
{
public:
virtual int common_func() = 0;
virtual ~Interface1() {};
};
class Interface2 : public Interface1 {
public:
virtual int common_func() = 0;
virtual int new_func() = 0;
virtual ~Interface2() {};
};
class InterimClass : public Interface2 {
public:
virtual int common_func() {
return 10;
}
};
class MostDerivedClass : public InterimClass {
public:
virtual int new_func() {
return 20;
}
};
int test_func()
{
Interface1 * i1 = new MostDerivedClass;
int x = i1->common_func();
cout << "The value = " << x << endl;
Interface2 * i2 = new MostDerivedClass;
x = i2->common_func();
return 0;
}
Let the second interface be derived from the first interface, remove the declaration of virtual int common_func() = 0; from the second interface, & use the keyword virtual to guide the compiler to the implementation.
class Interface1 {
public:
virtual int common_func() = 0;
virtual ~Interface1() {};
};
class BaseClass : public virtual Interface1 {
public:
virtual int common_func() {
return 10;
}
};
class Interface2 : public virtual Interface1{
public:
virtual int new_func() = 0;
virtual ~Interface2() {};
};
class DerivedClass : public virtual BaseClass, public virtual Interface2 {
public:
virtual int new_func() {
return 20;
}
};
Related
I have examined a few posts but nothing seemed to cover my question.
I have an interface full of pure virtuals.
I have an implementation class of the interface which is made up from various public base classes.
Even though the methods are available at the implementation class the error says the virtuals are not implemented.
Remove the interface from the implementation and it is perfect.
Why aren't the implementation methods linked through to the interface?
Here is the code...
class FunctionalClass1 {
public:
int result1(int _r) {
return 1;
}
int result2(int _r) {
return 2;
}
};
class FunctionalClass2 {
public:
int result3(int _r) {
return 3;
}
int result4(int _r) {
return 4;
}
};
class MyInterface {
public:
virtual int result1(int _r) = 0;
virtual int result2(int _r) = 0;
virtual int result3(int _r) = 0;
virtual int result4(int _r) = 0;
};
class ImplementationClass1 : public FunctionalClass1, public FunctionalClass2 {
};
class ImplementationClass2 : public FunctionalClass1, public FunctionalClass2, public MyInterface {
};
ImplementationClass1* ic1 = new ImplementationClass1(); // perfect, has all the methods available
ImplementationClass2* ic2 = new ImplementationClass2(); // fails because interface not implemented
1>X:\VisualStudioRepository\...\Main.cpp(37,57): error C2259: 'ImplementationClass2': cannot instantiate abstract class
1>X:\VisualStudioRepository\...\mainclass.h(33,7): message : see declaration of 'ImplementationClass2'
1>X:\VisualStudioRepository\...\Main.cpp(37,57): message : due to following members:
1>X:\VisualStudioRepository\...\Main.cpp(37,57): message : 'int MyInterface::result1(int)': is abstract
1>X:\VisualStudioRepository\...\mainclass.h(24,14): message : see declaration of 'MyInterface::result1'
1>X:\VisualStudioRepository\...\Main.cpp(37,57): message : 'int MyInterface::result2(int)': is abstract
1>X:\VisualStudioRepository\...\mainclass.h(25,14): message : see declaration of 'MyInterface::result2'
1>X:\VisualStudioRepository\...\Main.cpp(37,57): message : 'int MyInterface::result3(int)': is abstract
1>X:\VisualStudioRepository\...\mainclass.h(26,14): message : see declaration of 'MyInterface::result3'
1>X:\VisualStudioRepository\...\Main.cpp(37,57): message : 'int MyInterface::result4(int)': is abstract
1>X:\VisualStudioRepository\...\mainclass.h(27,14): message : see declaration of 'MyInterface::result4'
I do not understand by public methods of the implementation class are not linked through to the interface. It would be nice if someone could explain why it fails. It would be great if someone could provide a solution.
Many Thanks :)
One way to achieve what you want would be to have FunciontalClass1 and FunctionalClass2 implement MyInterface:
class FunctionalClass1 : public virtual MyInterface {
public:
int result1(int _r) override {
return 1;
}
int result2(int _r) override {
return 2;
}
};
class FunctionalClass2 : public virtual MyInterface{
public:
int result3(int _r) override {
return 3;
}
int result4(int _r) override {
return 4;
}
};
class ImplementationClass2 : public FunctionalClass1, public FunctionalClass2 {
};
Note that these classes will now be abstract because they have un-implemented virtual methods. Also MyInterface needs to be virtually inherited so that ImplementationClass2 only gets a single MyInterface parent.
Another option is to provide overrides in ImplementationClass2 that delegate to FunctionalClass1 and FunctionalClass2:
class ImplementationClass2 : public FunctionalClass1, public FunctionalClass2, public MyInterface {
public:
int result1(int _r) override {
return FunctionalClass1::result1(_r);
}
int result2(int _r) override {
return FunctionalClass1::result2(_r);
}
int result3(int _r) override {
return FunctionalClass2::result3(_r);
}
int result4(int _r) override {
return FunctionalClass2::result4(_r);
}
};
I have a top API (based on abstract class) which is composed by a base API (that will be reused by different top APIs).
class api_base {
public:
virtual int foo() = 0;
};
class api_top : public api_base {
public:
virtual int bar() = 0;
}
Then, I want to provide a base implementation for base API:
class imp_base {
public:
int foo() { return 1; }
}
And finally implement top API using base implementation for those functions defined in base API:
class imp_top : public api_top, public imp_base {
public:
int bar() { return 1; }
}
When I instantiate an object of imp_top type, compiler say that foo() function is not implemented. But that is not true, since imp_top derives from imp_base, which do have foo() function implemented.
Any advice about this?
Thank you in advance.
Full test code:
#include <stdio.h>
class api_base {
public:
virtual int foo() = 0;
};
class api_top : public api_base {
public:
virtual int bar() = 0;
};
class imp_base {
public:
int foo() { printf("foo from imp_base\n"); }
};
class imp_top : public api_top, public imp_base {
public:
int bar() { printf("bar from imp_top\n"); }
};
int main()
{
printf("Hello\n");
imp_top a;
a.bar();
a.foo();
return 1;
}
Compiler result:
test.cpp:26:12: error: cannot declare variable ‘a’ to be of abstract type ‘imp_top’
imp_top a;
^
test.cpp:18:7: note: because the following virtual functions are pure within ‘imp_top’:
class imp_top : public api_top, public imp_base {
^
test.cpp:5:17: note: virtual int api_base::foo()
virtual int foo() = 0;
^
test.cpp:29:6: error: request for member ‘foo’ is ambiguous
a.foo();
^
test.cpp:15:9: note: candidates are: int imp_base::foo()
int foo() { printf("foo from imp_base\n"); }
^
test.cpp:5:17: note: virtual int api_base::foo()
virtual int foo() = 0;
First Always use override keyword when redefining the functions in child classes.
Second read about virtual inheritance.
The following works :
class api_base {
public:
virtual int foo() = 0;
};
class api_top : public virtual api_base {
public:
virtual int bar() = 0;
};
class imp_base : public virtual api_base {
public:
int foo() override { printf("foo from imp_base\n"); return 0; }
};
class imp_top : public api_top, public imp_base {
public:
int bar() override { printf("bar from imp_top\n"); return 0; }
};
int main(){
imp_top a;
a.bar();
a.foo();
return 1;
}
Change:
class api_top : public api_base to class api_top : public virtual api_base
and:
class imp_base to class imp_base : public virtual api_base
Then it works.
To understand this, see: virtual inheritance. And yes (just saw Ext3h's post), use the override keyword.
You should have used the override keyword, then you would had noticed that you did not implement the interface but defined an entirely new foo() method.
You will need to derive both imp_base and api_top from api_base by virtual inheritance.
For code below, are there any other ways to access a method in base through interface?
struct Base {
void funct_base() {
printf("Common function for class Foo and class Bar\n");
}
};
struct IFoo {
virtual ~IFoo() {}
virtual void funct_a() = 0;
// would like to access Base::bunct_base() from here
};
struct Foo : public Base, public IFoo {
virtual void funct_a() {
printf("I am Foo:: funct A\n");
}
};
class IBar {
virtual ~IBar() {}
virtual void funct_a() = 0;
// would like to access Base::bunct_base() from here
};
class Bar : public Base, public IBar {
virtual void funct_a() {
printf("I am Bar:: funct A\n");
}
};
I know this can be done, but I just do not like the wrapper, it does not seem clean:
struct IBar {
virtual ~IBar() {}
virtual void funct_a() = 0;
virtual void funct_base() = 0;
};
struct Bar : public Base {
virtual void funct_a() {
printf("I am Bar:: funct A\n");
}
virtual void funct_base() {
Base::funct_base();
}
};
EDIT:
The question is, there is one base class, and two different derived classes that inherit from the same base class. Is there a way to access a base class method through derived class interface without adding a base class method wrapper?
Use a abstract base class IBase with a Abstract method funct_base and make the interface class a Virtual base classes of the classes Base, IFoo and IBar:
struct IBase {
virtual void funct_base() = 0;
};
struct Base : public virtual IBase {
virtual void funct_base() override { printf("Common function for class Foo and class Bar\n"); }
};
struct IFoo : public virtual IBase {
virtual void funct_a() = 0;
};
struct Foo : public IFoo, public Base {
virtual void funct_a() override { printf("I am Foo:: funct A\n"); }
};
class IBar : public virtual IBase {
virtual void funct_a() = 0;
};
class Bar : public IBar, public Base {
virtual void funct_a() override { printf("I am Bar:: funct A\n"); }
};
class Base{
protected:
int remainItems = 0;
public:
Base(){}
virtual int numOfItem() = 0;
};
class Deveried1 : public Base{
public:
Deveried1() :Base(){ remainItems = numOfItem(); }
int numOfItem(){
return 5;
}
};
class Deveried2 : public Base{
public:
Deveried2() :Base(){ remainItems = numOfItem(); }
int numOfItem(){
return 10;
}
};
class Deveried3 : public Base{
public:
Deveried3() :Base(){ remainItems = numOfItem(); }
int numOfItem(){
return 10;
}
};
int main(){
Base* foo = new Deveried3;
}
With this design, for every deveried class, I must do the same thing in constructor to initalize remainItems. I'd like to know if there are some better way/pattern in this situation.
Indeed, you can't call derived class functions from the base class constructor, so this kind of twisted inversion of dependencies can't work. I'd pass the value to the base-class constructor:
Base(int numOfItems) : remainItems(nomOfItems) {}
Derived1() : Base(5) {}
Derived2() : Base(10) {}
I do not see any benefit in the method, so I removed it and added an option to pass the variable in the base class constructor:
class Base{
protected:
int remainItems;
public:
Base(remainItems = 0) { this->remainItems = remainItems; }
};
class Deveried1 : public Base{
public:
Deveried1() :Base(5){}
}
};
class Deveried2 : public Base{
public:
Deveried2() :Base(10){}
}
};
class Deveried3 : public Base{
public:
Deveried3() :Base(10){}
}
};
int main(){
Base* foo = new Deveried3;
}
I believe what you're looking for is called the Non-Virtual Interface pattern.
How to implement an interface class using the non-virtual interface idiom in C++?
I have 3 interface (pure virtual) classes like this
class A {
virtual void M1() = 0;
virtual void M2() = 0;
};
class B : public A {
virtual void M3() = 0;
};
class C : public A {
virtual void M4() = 0;
};
I have the implementers like this
class Aimpl : A {
void M1 () override {};
void M2 () override {};
}
class Bimpl: public Aimpl, public B{
void M3() override {};
}
class Cimpl: public Aimpl, public C{
void M4() override {};
}
and
Bimpl b = Bimpl();
b.M2() // Error. M2 is ambigous. Can be from Aimpl or A
what's a simple way to fix this? I want to be able to pass around B or C in functions rather than Bimpl
Essentially, you have two different M2 methods in Bimpl: Aimpl::M2 and B::M2. You have run into the diamond-inheritance problem.
To fix it, you should use virtual inheritance. This question provides a very good overview. Essentially, you should use something like this:
class A {
virtual void M1() = 0;
virtual void M2() = 0;
};
class B : public virtual A {
virtual void M3() = 0;
};
class C : public virtual A {
virtual void M4() = 0;
};
class Aimpl : public virtual A {
void M1 () override {};
void M2 () override {};
};
class Bimpl: public virtual Aimpl, public virtual B {
void M3() override {};
};
class Cimpl: public virtual Aimpl, public virtual C {
void M4() override {};
};
Note that I'm not super super familiar with virtual inheritance, so this may or may not be the best way to apply virtual inheritance.