Separation of interface from implementation in an inheritance hierarchy (C++ newbie) - c++

I am trying to figure out how to arrange some classes. This is what I've got so far ...
The top of the inheritance hierarchy is (naturally) T:
(T.h)
namespace foo
{
class T
{
public:
virtual void method1(std::string a_parameter) = 0;
virtual void method2() = 0;
};
}
I have two sub-classes of T with some additional methods - here are
the header files:
(A.h)
namespace foo
{
class A : public T
{
public:
virtual ~A() {};
virtual void method3() = 0;
//and a factory function
static A* gimmeAnAyy();
};
}
(B.h)
namespace foo
{
class B : public T
{
public:
virtual ~B() {};
virtual void method4() = 0;
//and a factory function
static B* gimmeABee();
};
}
The implementation classes are in the respective .cpp files:
(A.cpp)
namespace foo
{
class AImpl : public A
{
public:
A(std::string member_data) : m_member_data(member_data) {};
~A() {};
void method3()
{
//something really important, can't think of it right now ;-)
};
private:
std::string m_member_data;
};
A* A::gimmeAnAyy()
{
return new AImpl("this is an impl of A");
};
}
(B.cpp)
namespace foo
{
class BImpl : public B
{
public:
B(std::string other_data) : m_other_data(other_data) {};
~B() {};
void method4()
{
//something really important, can't think of it right now ;-)
};
private:
std::string m_other_data;
};
B* B::gimmeABee()
{
return new BImpl("this is an imll of B");
};
}
Now the compiler complains - rightly so - about the virtual functions
method1() and method2() that I haven't implemented in AImpl and BImpl.
What I want is a TImpl class that both AImpl and BImpl can inherit from
so that I don't have to implement method1() and method2() in two different .cpp files.
Is it possible? Am I out to lunch? Am I asking too many rhetorical questions for a StackExchange post?
Thanks in advance,
Mike

Yeah, it is possible. Common practice is to use the following snippet:
template<typename Interface>
class TImpl : public Interface
{
public:
virtual void method1(std::string a_parameter) { /* implementation */ }
virtual void method2() { /* implementation */ }
};
And then inherit from it as follows:
class Aimpl : public TImpl<A>
{
public:
virtual void method3() { /* implementation */ }
};
class Bimpl : public Timpl<B>
{
public:
virtual void method4() { /* implementation */ }
};
You can put implementation of Timpl in cpp file, but then you have to explicitly instantiate it for every possible interface. This is done as follows in the cpp:
template<typename Interface>
void Timpl<Interface>::method1(std::string a_parameter)
{
/* implementation */
}
template<typename Interface>
void Timpl<Interface>::method2()
{
/* implementation */
}
template class Timpl<A>;
template class Timpl<B>;

Do not make method1 and method2 pure virtual functions. Give them an implementation!
i.e.
declare
class T
{
public:
virtual void method1(std::string a_parameter);
virtual void method2();
};
Define:
void T::method1(std::string a_parameter) { // Could use const/reference here perhaps
....
}
etc...

It seems your problem is the wrong believe that it is better to have only pure virtual functions in your base class! Just get over it and provide a default implementation in T. Although there are religious believes that is bad, there isn't any technical reason not to have it. Insisting in having only pure virtual functions in base classes is like insisting in all music having to be 12-tone music!

since both of the son classes (A & B) don't have (method1, method2) then you don't have to use the virtual. you can easily provide a default implementation in the base class and then invoke and use these methods through the inheritance chain since the inheritance type here is public.

In the A and B classes declaration, the methods 3 and 4 are pure virtual, so in the definition file you shouldn't gives an implementation of them. In my understand A and B are leading the implementation of the T methods and their own virtual methods to other concrete classes who inherit from them. If you thing that A and B are concrete classes, put away the "= 0" from the following lines:
class A : public T
{
public:
virtual ~A() {};
virtual void method3() = 0; // <-- Here
//and a factory function
static A* gimmeAnAyy();
};
class B : public T
{
public:
virtual ~B() {};
virtual void method4() = 0; // <-- and Here
//and a factory function
static B* gimmeABee();
};
If doesn't want to implement the methods 1 and 2 of the T class, give an empty or a default implementation to them, in the T class or in the A and B classes.
But consider this, if you inherits from an interface, is expected that you IMPLEMENT that interface. :)

Related

hierarchical interfaces and implementations

The following code only works if you uncomment the line
virtual void FuncA() { ImplA::FuncA(); }
in class ImplB, otherwise I get compiler error:
cannot instantiate abstract class ... FuncA(void)' : is abstract
Question is why doesn't it get the implement for FuncA() from the inherited ImplA?
class InterfaceA {
public:
virtual void FuncA()=0;
};
class InterfaceB : public InterfaceA {
public:
virtual void FuncB()=0;
};
class ImplA : public InterfaceA {
public:
virtual void FuncA() { printf("FuncA()\n"); }
};
class ImplB : public ImplA, public InterfaceB {
public:
// virtual void FuncA() { ImplA::FuncA(); }
virtual void FuncB() { printf("FuncB()\n"); }
};
{
ImplB *b = new ImplB();
InterfaceA *A= b;
A->FuncA();
InterfaceB *B= b;
B->FuncB();
B->FuncA();
}
You've hit an instance of the "diamond" problem in multiple inheritance.
You'll need to use "virtual" inheritance (which amounts to adding the keyword virtual when inheriting)
The problem is that ImplB has two paths to the base class InterfaceA. However, your intention is that the interfaces do not provide any implementation. Thus, you need to indicate this to the compiler, so it can unify the pure virtual functions.
For a much better explanation:
http://www.cprogramming.com/tutorial/virtual_inheritance.html
I've modified your code to add virtual when you inherit from interfaces. Now it compiles, even with the line commented. Also note, I think you are missing virtual destructors, so you'll have some other problems down the line. This code compiles, without uncommenting FuncA.
#include <cstdio>
class InterfaceA {
public:
virtual void FuncA()=0;
};
class InterfaceB : public virtual InterfaceA {
public:
virtual void FuncB()=0;
};
class ImplA : public virtual InterfaceA {
public:
virtual void FuncA() { printf("FuncA()\n"); }
};
class ImplB : public ImplA, public virtual InterfaceB {
public:
// virtual void FuncA() { ImplA::FuncA(); }
virtual void FuncB() { printf("FuncB()\n"); }
};
int main()
{
ImplB *b = new ImplB();
InterfaceA *A= b;
A->FuncA();
InterfaceB *B= b;
B->FuncB();
B->FuncA();
}
Multiple inheritance isn't "mixins"
You can inherit from multiple classes that have methods with the same name but that doesn't make them the same.
The thing that inherits from a virtual class must implement the pure virtual functions of its parents.
If the method names weren't scoped, you could end up with combinations of parent classes that were mutually exclusive to inherit from because the implementations of the method with the shared name wouldn't be compatible.
I am a bit surprised that putting using ImplA::FuncA; in ImplB doesn't solve it, though: https://gcc.godbolt.org/

Implementing a class hierarchy properly

Say I have an interface hierarchy :
class A
{
virtual void commonFunc() = 0;
};
class B1 : public A
{
virtual void b1SpecificFunc() = 0;
};
class B2 : public A
{
virtual void b2SpecificFunc() = 0;
};
Interface A only exist to avoid duplicating the commonFunc() function.
Now if I want to implement this in order to have 2 instanciatable classes ImplB1 and ImplB2 i could do :
class ImplA
{
virtual void commonFunc();
};
class ImplB1 : public ImplA
{
virtual void b1SpecificFunc();
};
class ImplB2 : public ImplA
{
virtual void b2SpecificFunc();
};
The problem with this is that it makes ImplA instanciatable, which I don't want to. I only want ImplB1 and ImplB2 to be instanciatable, because ImplA is something asbtract that only exist to have the implementation of the common function in common.
How could i design this please ? Thank you.
Interface A only exist to avoid duplicating the commonFunc() function.
You certainly mean to avoid duplicating its declaration, don't you?
class ImplA
{
virtual void commonFunc();
};
This should probably be:
class ImplA : public A
{
virtual void commonFunc();
};
And I guess the point is that ImplA actually has an implementation of commonFunc. So for the sake of this answer's brevity, let's put it into the class definition:
class ImplA : public A
{
virtual void commonFunc() {} // implementation
};
The problem with this is that it makes ImplA instanciatable.
Just make ImplA's destructor pure virtual:
class ImplA : public A
{
public:
virtual ~ImplA() = 0 {}
private:
virtual void commonFunc() {}
};
This will prevent instantiation even inside of derived classes' functions. For example, the following will create a compiler error:
class ImplB1 : public ImplA
{
public:
virtual void b1SpecificFunc()
{
ImplA a; // error, cannot instantiate abstract class
}
};
In fact, you will not even be able to instantiate the class in its own functions:
class ImplA : public A
{
public:
virtual ~ImplA() = 0 {}
private:
virtual void commonFunc()
{
ImplA a; // error, cannot instantiate abstract class
}
};
But seriously, this all seems pretty over-engineered. Perhaps what you really need is to make commonFunc a non-virtual protected function of A, which derived classes can then call if they need to.
Or perhaps commonFunc can just be a free-standing utility function?
You can do the following. Also, here is a SO question/answer about this.
Note: While I'm answering the question that you can do this I'm not asserting it's what you should do.
Code
#include <iostream>
class A
{
public:
virtual void commonFunc() = 0;
};
void A::commonFunc() // Pure virtual but implemented anyway
{
// Derived classes can explicitly opt-in to this implementation
std::cout << "A::commonFunc()\n";
}
class B1 : public A
{
public:
virtual void b1SpecificFunc() = 0;
};
class B2 : public A
{
virtual void b2SpecificFunc() = 0;
};
class ImplB1 : public B1
{
public:
// This function must be implemented because its declared pure virtual
virtual void commonFunc()
{
// Can override the behavior if desired...
A::commonFunc(); // Explicitly use default implementation
}
virtual void b1SpecificFunc()
{
std::cout << "b1SpecificFunc()\n";
}
};
class ImplB2 : public B2
{
public:
// This function must be implemented because its declared pure virtual
virtual void commonFunc()
{
// Can override the behavior if desired...
A::commonFunc(); // Explicitly use default implementation
}
virtual void b2SpecificFunc()
{
std::cout << "b2SpecificFunc()\n";
}
};
int main()
{
//A a; // Won't compile (as expected/desired)
ImplB1 b1;
ImplB2 b2;
b1.commonFunc();
b1.b1SpecificFunc();
b2.commonFunc();
b2.b2SpecificFunc();
return 0;
}
Output
A::commonFunc()
b1SpecificFunc()
A::commonFunc()
b2SpecificFunc()

C++: How to implement function in a parent interface with a base class?

Consider following hierarchy:
class Interface {
public:
virtual void foo() = 0;
};
class SubInterface: public Interface {
public:
virtual void bar() = 0;
};
class Base: public Interface {
public:
void foo() {};
};
class Impl: public SubInterface, public Base {
public:
void bar() {};
};
There are several sub interfaces which offer other methods in addition to foo().
There can be several implementing classes to a sub interface.
foo() is always implemented the same way.
Here is an example which simulates how these classes would be used:
int main() {
SubInterface* view1 = new Impl(); // Error! Interface::foo() is pure virtual within Impl
view1->foo();
view1->bar();
Interface* view2 = view1;
view2->foo();
}
Why can't the compiler see that Interface::foo() is implemented in Base which Impl inherits from?
I figured that I could implement foo() in Impl explicitly and delegate the call to Base like this:
class Impl: public SubInterface, public Base {
public:
void foo() {
Base::foo();
}
void bar() {};
};
However, I would have to do that for all classes which implement a sub interface, so this way isn't exactly ideal. Is there a better solution?
SubInterface and Base should inherit virtually from Interface otherwise you are creating ambiguity in form of the dreaded diamond
Basically, what happens is that Impl contains two 'instances' of Interface.
Here is why - follow the diagram:

Abstract interface inheritance

Must virtual methods be always implemented in derived class?
Can I write something like this?
<!-- language: lang-cpp -->
class BaseInterface
{
public:
virtual void fun_a() = 0;
virtual void fun_b() = 0;
virtual ~BaseInterface();
};
class Derived : public BaseInterface
{
void fun_a() { ... };
};
class FinalClass : public Derived
{
void fun_b() { ... };
}
int main()
{
FinalClass test_obj;
test_obj.fun_a(); // use Derived implementation or fail ???
test_obj.fun_b(); // use own implementation
BaseInterface* test_interface = new FinalClass();
test_interface->fun_a(); // fail or ok ???
test_interface->fun_b();
}
Is the code above correct?
Does another virtual method outflank exist?
Pure virtual methods always must be reimplemented in derived class?
Actually a derived class which is going to be instantiated.
In your code, you didn't make an object from Derived so it's OK.
Can i write something like this?
Yes.
You had some minor errors that I corrected them:
class BaseInterface
{
public:
virtual void fun_a() = 0;
virtual void fun_b() = 0;
virtual ~BaseInterface() {}; // You forget this
};
class Derived : public BaseInterface
{
public:
void fun_a() {} // This should be public as its base
};
class FinalClass : public Derived
{
public:
void fun_b() {} // This should be public as its base
};
int main()
{
FinalClass test_obj;
test_obj.fun_a();
test_obj.fun_b();
BaseInterface* test_interface = new FinalClass();
test_interface->fun_a();
test_interface->fun_b();
}
It makes Derived also an abstract class which you cannot instantiate, seeing you don't implement all the virtual functions from it's base, it becomes an abstract class you cannot directly instantiate.
See here: liveworkspace.org/code/6huYU$10
For the rest, your code should work.
Code is correct.
There is no special concept for interface in C++. All are classes. Some of the class methods can be pure virtual. It only means that compiler cannot create an instance of such class.

C++ is it possible to make a class extend one class and be a realization of an interface at the same time?

Coluld you provide a simple code example? (sorry C++ nube) and how to call a function from the class you are extending?
A bit useful example: :-)
class CImplementation
{
public:
void doFoo();
};
void CImplementation::doFoo()
{
//implementation
}
class IInterface
{
public:
virtual void foo()=0;
};
class DerivedFromImplementationAndInterface : public CImplementation, public IInterface
{
virtual void foo();
};
void DerivedFromImplementationAndInterface::foo()
{
doFoo();
}
//possible usage:
void method(IInterface& aInterface)
{
aInterface.foo();
}
void test()
{
IInterface* d = new DerivedFromImplementationAndInterface;
method(*d);
}
In C++, you can extend multiple classes, it's called multiple inheritance. Most probably this is what you're looking for. Please read a good book about multiple inheritance and C++ (a quick introduction: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr134.htm), because there are many pitfalls and details to pay attention to.
Example for multiple inheritance:
class A { ... };
class B { ... };
class C: public A, public B {}; // C inherits from A and B.
C++ doesn't explicitly have interfaces, the equivalent of an interface in Java is usually implemented with a class having only pure virtual functions (plus constructors, destructor, copy assignment):
#include <iostream>
// interface
class Fooable {
public:
virtual int foo() = 0;
virtual ~Fooable() {}
};
// base class
class Base {
public:
void non_virtual_function() { std::cout << "Base::non_virtual_function\n"; }
virtual void virtual_function() { std::cout << "Base::virtual_function\n"; }
};
// derived class, inherits from both Base "class" and Fooable "interface"
class Derived: public Base, public Fooable {
public:
virtual int foo() {
// call base class function
Base::non_virtual_function();
// virtual call to function defined in base class, overridden here
virtual_function();
}
virtual void virtual_function() {
// call base class implementation of virtual function directly (rare)
Base::virtual_function();
std::cout << "Derived::virtual_function\n";
}
void non_virtual_function() {
// not called
std::cout << "Derived::non_virtual_function\n";
}
};
int main() {
Derived d;
d.foo();
}
Not sure what you're asking:
class A
{
public:
void method();
};
class B
{
public:
void method();
};
class C : public A, public B
{
public:
void callingMethod();
};
void C::callingMethod()
{
// Here you can just call A::method() or B::method() directly.
A::method();
B::method();
}
Note that multiple inheritance can lead to really hard-to-solve problems and I would recommend to only use it when necessary.
The question as stated,
C++ is it possible to make a class extend one class and implement another?
does not make much sense. The answer to that is just "yes". You can derive from any number of classes: C++ fully support multiple inheritance.
So, given that the question as stated isn't really meaningful, it's at least possible that you meant to ask
C++ is it possible to make a class extend one class and thereby implement another?
The answer to this question is also yes, but it's not trivial. It involves virtual inheritance. Which is quite tricky.
Here's an example:
#include <iostream>
void say( char const s[] ) { std::cout << s << std::endl; }
class TalkerInterface
{
public:
virtual void saySomething() const = 0;
};
class TalkerImpl
: public virtual TalkerInterface
{
public:
void saySomething() const
{
say( "TalkerImpl!" );
}
};
class MyAbstractClass
: public virtual TalkerInterface
{
public:
void foo() const { saySomething(); }
};
class MyClass
: public MyAbstractClass
, public TalkerImpl
{};
int main()
{
MyClass().foo();
}
The virtual inheritance ensures that there is only one sub-object of type TalkerInterface in a MyClass instance. This has some counter-intuitive consequences. One is that "inheriting in an implementation" works, and another is that construction of that base class sub-object happens down in each MyClass constructor, and more generally down in the most derived class.
Cheers & hth.,