considering following code:
#include <stdio.h>
struct ITimer {
virtual void createTimer() = 0;
};
class A : public ITimer
{
public:
void showA() {
printf("showA\n");
createTimer();
}
};
class B : public ITimer
{
public:
void showB() {
printf("showB\n");
}
void createTimer() {
printf("createTimer");
}
};
class C: public A, public B
{
public:
void test() {
showA();
showB();
}
};
int main()
{
C c;
c.test();
return 0;
}
I need to use interface ITimer in class A, but the method is implemented in class B. So I inherited the interface in A, but the compiler is not happy with it:
test.cc
test.cc(38) : error C2259: 'C' : cannot instantiate abstract class
due to following members:
'void ITimer::createTimer(void)' : is abstract
test.cc(5) : see declaration of 'ITimer::createTimer'
How could I use the interface in baseclass A while its method is implemented in class B.
Thanks.
Inheritance is the base-class of all evil.
A nor B are ITimers
A doesn't even implement the pure virtual, so it cannot be instantiated. Therefore, inheriting from A makes C abstract too (cannot be instantiated).
You don't want to use inheritance here. See
Liskov Substitution Principle ("is-a" rule)
In this case, the dreaded diamond-of-death hierarchy could be fixed by adding virtual:
class A : public virtual ITimer
//...
class B : public virtual ITimer
See it Live on IdeOne. I don't recommend this, though. Consider fixing the design.
See also Diamond inheritance (C++)
Related
Consider the following example:
class A{
public: virtual void hello() = 0;
};
class B: public A{};
class C {
public: void hello(){
cout<<"Hi";
}
};
class D: public B, public C{};
The idea is that I would like to inject the implementation of hello into D through C. This doesn't seem to work unless I make C inherit from A too. Since that leads to diamond inheritance, I end up using virtual inheritance.
Is there any alternative to forcing an implementation into a derived class, without disturbing the abstract classes A and B here?
EDIT: I want a solution where I don't need to explicitly write code within D. This is because, I have many classes like D having the same implementation, which is exactly why I would like to push that implementation up to some class from which all of them inherit.
You can rewrite C as a template class that inherits from it's template argument and then derive D from C.
template <class Base>
class C : public Base {
public: void hello(){
cout<<"Hi";
}
};
class D: public C<B> {};
You can consider static inheritance/ policy classes when you need to inject an outside method into a class hierarchy. Note that injecting the method usually means that the method does not have the same name as an existing virtual in the class hierarchy (if it does, you are forced to use virtual inheritance or explicitly call with the scope :: or insert it in the class hierarchy). I called the method externalHello here.
The other options work fine as well but they conceptually point more to the fact that the injected method is not really an abstract method that could be used outside of this class hierarchy but should have been part of it in the first place.
class A
{
public:
virtual void hello() = 0;
};
class B: public A
{
public:
void hello()
{
cout<<"Hi from B" << endl;
};
};
template<typename T> class C1
{
public:
void injectedMethodUnrelatedToClassHierarchy()
{
cout<<"Hi from C1 with unrelated method" << endl;
};
void externalHello()
{
static_cast<T*>(this)->hello(); // will still call hello in B
injectedMethodUnrelatedToClassHierarchy(); // this will call hello here
};
};
class D: public B, public C1<D>{};
With client code:
D dx;
dx.hello();
dx.externalHello();
dx.injectedMethodUnrelatedToClassHierarchy();
It may work
#include<iostream>
using namespace std;
class A
{
public:
virtual void hello() = 0;
};
class C {
public: void hello(){
cout<<"Hi\n";
}
};
template<typename T>
class B: public A, public T
{
public:
void hello() override{ //override A::hello()
//do other staff
T::hello(); // call C::hello()
}
};
class D: public B<C>{
};
int main()
{
D d;
d.hello();
return 0;
}
Lets suppose you want to make an interface of the class Derived and it looks like this:
class Derived : public Base
{
public:
foo();
}
class Base
{
public:
tii();
//many other methods
}
How would you do the Interface? How can you make Base::tii visible (and also other methods) to this new interface?
class IDerived
{
public:
virtual foo() = 0;
// should I declare here tii() as a pure virtual function?
// but by doing it now there is ambiguity!
}
What is a good strategy?
The new Derived class should look like this....
class Derived : public Base, public IDerived
{
//implement the real thing
}
Your example is doing things backwards: the interface should be defined independently of any concrete classes with all pure virtual methods:
class IDerived
{
public:
virtual void foo() = 0;
virtual ~IDerived() {} // don't forget to include a virtual destructor
}
And the concrete classes will derive publicly from the interface:
class Derived : public Base, public IDerived
{
public:
void foo();
}
If you want IDerived to also declare methods that Derived inherits from Base, you can have Derived explicitly implement the method by calling the inherited implementation:
class Derived : public Base, public IDerived
{
public:
void foo();
void bar() { Base::bar(); }
}
At front, I dislike interfaces (they are grown by other languages than c++).
Anyway, if you have one, it should be complete: Hence have the 'tii() as a pure virtual function'. To resolve the conflict rewrite that function in 'Derived' (forward to Base::tii).
I am trying to define interface types in C++ using abstract classes and implement them with concrete classes. The problem I am running into is that I cannot both inherit and interface from another interface and inherit the implementation from a base concrete class.
My goal is to be able to define a hierarchy of interfaces which may inherit from less complex base interfaces. I also want to be able to extend the implementation of interfaces by inheriting from concrete classes (like inheriting from TObjectA in the example below).
This is what I have. The error I am getting is "object of abstract class type "TObjectB" is not allowed". I believe I know why, which is because I didn't implement MethodA() in TObjectB. But I really want is to have the implementation provided by a base class (TObjectA) and still have interface hierarchies (IInterfaceB inherits from IInterfaceA). I also don't want to repeat all the inherited interface methods in my derived concreate classes. How can I do this?
class IInterfaceA
{
public:
virtual void MethodA() = 0;
};
class IInterfaceB : IInterfaceA
{
public:
virtual void MethodB() = 0;
};
class TObjectA : public IInterfaceA
{
public:
void MethodA() { cout << "Method A"; }
};
class TObjectB : public TObjectA, public IInterfaceB
{
public:
void MethodB() { cout << "Method B"; }
};
void TestInterfaces()
{
IInterfaceB* b = new TObjectB(); // error: object of abstract class type "TObjectB" is not allowed
b->MethodB();
delete b;
}
In your class hierarchy, TObjectB actually has two IInterfaceA base class subobjects: one inherited through IInterfaceB and one inherited through TObjectA. The MethodA() from each of them needs to be implemented.
You need to inherit from the interface classes using public virtual inheritance, which ensures there is only a single base class subobject of each interface class type:
class IInterfaceA
{
public:
virtual void MethodA() = 0;
};
class IInterfaceB : public virtual IInterfaceA
{
public:
virtual void MethodB() = 0;
};
class TObjectA : public virtual IInterfaceA
{
public:
void MethodA() { cout << "Method A"; }
};
class TObjectB : public TObjectA, public virtual IInterfaceB
{
public:
void MethodB() { cout << "Method B"; }
};
void TestInterfaces()
{
TObjectB b_object;
IInterfaceB& b = b_object;
b.MethodB();
}
Whether or not such complex class hierarchies are desirable is another matter altogether.
Your problem is caused by the dreaded diamond inheritance. You've implemented TObjectA::IInterfaceA::MethodA but not IInterfaceB::IInterfaceA::MethodA.
My recommendation would be to make IIterfaceA and IIterfaceB completely independent. If that's not possible, you can look into virtual inheritance.
I have not programmed in c++ in a long time and want some simple behavior that no amount of virtual keywords has yet to produce:
class Base {
public:
int both() { return a(); }
};
class Derived : public Base {
protected:
int a();
};
class Problem : public Derived {
};
Problem* p = new Problem();
p.both();
Which gives me a compile-time error. Is this sort of behavior possible with c++? Do I just need forward declaration? Virtual keywords on everything?
No. You will have to use a pure virtual a in base.
class Base {
virtual int a() = 0;
int both() {
return a();
}
};
You should declare the a() function as a pure virtual method in the Base class.
class Base {
int both() {
return a();
}
virtual int a()=0;
};
Then implement the a() method in the Derived class
class Derived : public Base {
int a(){/*some code here*/}
};
And finally, Problem class doesn't see the both() method, since its private in Base. Make it public.
class Base {
public:
int both() {
return a();
}
};
Your function both() is private by default. Try:
class Base {
public:
int both() {
// ...
(In the future, it would be helpful if you tell us what the actual error message was.)
You need a() to be declared in class Base, otherwise the compiler doesn't know what to do with it.
Also, both() is currently a private method (that's the default for classes), and should be made public in order to call it from main.
You have multiple problems in your code :
unless you declare them public or protected, elements of a class are private as a default.
you need a virtual keyword to define a virtual function that would be callable in a parent.
new returns a pointer to Problem.
Here's a complete working code based on your test :
class Base {
protected:
virtual int a()=0;
public:
int both() {
return a();
}
};
class Derived : public Base {
private :
int a()
{
printf("passing through a!");
return 0;
}
};
class Problem : public Derived {
};
int main(void)
{
Problem* p = new Problem();
p->both();
}
tested on CodePad.
As others point out, you need to declare a() as pure virtual method of Base and change access to public to make your snippet work.
Here is another approach possible in c++: instead of virtual functions, you can use static polymorphism via the Curiously recurring template pattern:
template <class D>
class Base : public D
{
public:
int both() { return D::a(); }
};
class Derived : public Base<Derived>
{
public:
int a();
};
I'm posting this approach since you're asking what is possible in c++. In practice, virtual methods are most often a better choice because of their flexibility.
I am trying to figure out an interesting multiple inheritance issue.
The grandparent is an interface class with multiple methods:
class A
{
public:
virtual int foo() = 0;
virtual int bar() = 0;
};
Then there are abstract classes that are partially completing this interface.
class B : public A
{
public:
int foo() { return 0;}
};
class C : public A
{
public:
int bar() { return 1;}
};
The class I want to use inherits from both of the parents and specifies what method should come from where via using directives:
class D : public B, public C
{
public:
using B::foo;
using C::bar;
};
When I try to instantiate a D I get errors for trying to instantiate an abstract class.
int main()
{
D d; //<-- Error cannot instantiate abstract class.
int test = d.foo();
int test2 = d.bar();
return 0;
}
Can someone help me understand the problem and how to best make use of partial implementations?
You don't have diamond inheritance. The B and C base classes of D each have their own A base class subobject because they do not inherit virtually from A.
So, in D, there are really four pure virtual member functions that need to be implemented: the A::foo and A::bar from B and the A::foo and A::bar from C.
You probably want to use virtual inheritance. The class declarations and base class lists would look like so:
class A
class B : public virtual A
class C : public virtual A
class D : public B, public C
If you don't want to use virtual inheritance then you need to override the other two pure virtual functions in D:
class D : public B, public C
{
public:
using B::foo;
using C::bar;
int B::bar() { return 0; }
int C::foo() { return 0; }
};
You need to make your base classes virtual in order for them to inherit properly. The general rule is that all non-private member functions and base classes should be virtual UNLESS you know what you're doing and want to disable normal inheritance for that member/base.