Inheritance, virtual interface classes, derived classes

Started by
12 comments, last by Mantear 18 years, 6 months ago
Greetings, I hope what I describe next makes sense. I have been given two interface classes (pure virtual/abstract classes). One interface says I must implement functions F(x) and G(x). The other interface says I must implement functions F(x) and H(x). The functionality of F(x) is identical to both classes. My initial thought was to make a base class, Bclass, that implements F(x). I'd then make two derived classes, Dclass1 and Dclass2. Dclass1 would inherit from Bclass, inherit the F(x) function, and implement G(x). Dclass2 would inherit from Bclass, inherit the F(x) function, and implement H(x). Pretty striaght forward and simple. Now, how do I make Dclass1 a derived class of the interface that says I must implement F(x) and G(x)? How do I do the same for Dclass2? Is it possible somehow for Dclass1 to inherit both Bclass and the abstract interface, implement G(x), and have the Bclass implementation of F(x) satisfy the requirement (from the abstract interface class) that Dclass1 implement F(x)? I could make them completely seperate entities, and duplicate the functionality of F(x). However, this code duplication seems undesirable, and I'm thinking there must be a way to avoid it. (Some notes: F(x) represents a lot of funcionality, say, 90% of what Dclass1 and Dclass2 will do, so it would be a lot of code duplication. G(x) and H(x) functionality are completely seperate/independant from each other. In other words, I wouldn't want a single class that implemented everything. They have to be two seperate classes. I have been given the interfaces as abstract classes and do not have the power to change them.)
Advertisement
Language?

Enigma
Sorry, forgot to mention. C++.
Quote:Original post by Mantear
Greetings,

I hope what I describe next makes sense.

I have been given two interface classes (pure virtual/abstract classes). One interface says I must implement functions F(x) and G(x). The other interface says I must implement functions F(x) and H(x). The functionality of F(x) is identical to both classes.

...

Now, how do I make Dclass1 a derived class of the interface that says I must implement F(x) and G(x)? How do I do the same for Dclass2? Is it possible somehow for Dclass1 to inherit both Bclass and the abstract interface, implement G(x), and have the Bclass implementation of F(x) satisfy the requirement (from the abstract interface class) that Dclass1 implement F(x)?


To do what you describe here, you'd simply:
#include <iostream>using std::cout;class a_interface {public:   virtual void common_method() = 0;           virtual void a_exclusive_method() = 0;};class b_interface {public:   virtual void common_method() = 0;           virtual void b_exclusive_method() = 0;};template< typename interface >class common_interface : public interface {public:   void common_method() { cout << "ab common\n";};};class a_object : public common_interface< a_interface > {public:   void a_exclusive_method() { cout << "a exclusive\n"; };};class b_object : public common_interface< b_interface > {public:   void b_exclusive_method() { cout << "b exclusive\n"; };};int main() {   a_object a;   b_object b;      a.common_method();   b.common_method();   // the template parameter interface forces these functions to be   // implemented in classes deriving from common_interface< interface >   a.a_exclusive_method();   b.b_exclusive_method();   return 0;}

Templates are your friend [smile]. As to whether this is the most optimal solution depends on what objects these interfaces abstract, the extent of which the common method is integrated into them and the specialization of their exclusive methods.

But this should at least give you a place to start from, then profile later.
:stylin: "Make games, not war.""...if you're doing this to learn then just study a modern C++ compiler's implementation." -snk_kid
Hmm, I haven't really dug into templates before. I have a C/embedded background, and am doing some C++ work now. Looks like I'll have to read up on templates. Always more to learn!

The reason for my dilema came about because I've been tasked with implementing a new feature. The new feature was designed with C++ in mind. However, we're under a CORBA environment, hence, the abstract interfaces. Neither the CORBA environment nor the design can be changed, so I'm stuck with what I have.

The best way to describe these objects are as Tx and Rx ports for data flow between two different programs. They have a lot in common. Port connections, base CORBA object setup stuff, etc. But their Tx and Rx characteristics, the direction of the data flow and what the ports do to the data in that direction, differ greatly. So my first thought was make a base class, and derive two others that deal specifically with the Tx/Rx. However, the CORBA IDL generated interface/abstract class, which I need to inherit, caused me great headaches. They had interfaces for both the commonly shared functions, as well as the specific Tx and Rx functions.
If the classes only need to share code and don't need to be treated as part of the same hierachy then you should consider making a class that implements F() and using either composition or private inheritance.

While the actual problem is rather convuluted, I suspect that virtual parents would solve the problem

class b : public virtual common

that will make it's parent actually be a reference thus if you have a class that extends b and another like b, they will both point to the same class common

hope that helps,
Indy
Nitage,

I'm not sure what you mean. I haven't heard of composition before, and I don't know how private inheritance would do anything usefull. Could you expand on your thoughts?


Arelius,

Making the base class virtual doesn't solve the problem with the interfaces. My problem can be generalized somewhat. Basically, how would you implement the situation where you have two interfaces/abstract classes that are similar, (that is, they share at least one common/identical function, but have at least one non-common funcion each).

-- What I have --
Interface1: contains pure virtual declarations of F(x) and G(x)
Interface2: contains pure virtual declarations of F(x) and H(x)

-- What I want --
Class1: Contains implementation of F(x) and G(x)
Class2: Contains implementation of F(x) and H(x)

F(x) is identical to both Classes.

If I make a base class for Class1 and Class2 that implements F(x), Class1 and Class2 would implement G(x) and H(x) respectively. However, at what point/how do I inherit the intefaces? If the base class inherits them (remember, they're pure virtuals), the base class would trickle down pure virtual declarations of G(x) and H(x) to both derived classes (which is undesirable). Both Class1 and Class2 would end up needing to implement functions that do not belong in them.


I hope I'm making sense. If I misunderstood either of your statements, please expand on your thoughts. I'm no C++ expert by any stretch and need further explainations.
It seems to me that you want these classes to share a function implementation but not to be polymorphically related - they have different interface (base) classes.

You have class Implementation1 which implements class Interface1.
You have class Implementation2 which implements class Interface2.

To use a common F() function in both classes you have several options:


The template option as stylin described.

Use a free function (that is a function which isn't a member function as F() and have Implementation1 and Implementation2 have F functions which call the free F function.

Have a class which implements F() and have Implementation1 and Implementation2 hold a member variable of that type (ths is composition).

Use private inheritance - Implementation1 & Implementation2 inherit publicly from their interfaces and privatley from a class which implements F. This option is probably the worst as it introduces multiple inheritance without really bringing you any benefit.
Quote:Original post by Mantear
If I make a base class for Class1 and Class2 that implements F(x), Class1 and Class2 would implement G(x) and H(x) respectively. However, at what point/how do I inherit the intefaces? If the base class inherits them (remember, they're pure virtuals), the base class would trickle down pure virtual declarations of G(x) and H(x) to both derived classes (which is undesirable). Both Class1 and Class2 would end up needing to implement functions that do not belong in them.


Essentially the template technique above does what you didn't want to do in your first post, ie., make two distinct classes and manually copy the functionality of f(x). If this is the behaviour you desire, then I think this is the easiest and clearest approach.

With composition, only the exclusive interfaces would be exposed, but you'd still have to duplicate the common functionality in both classes, which you wouldn't have to do if you used (virtual) inheritance. Many times you'll inherit based on an 'is-a' relationship, whereas composition is usually a 'has-a' relationship (subtle, but the difference is between "this object is that kind of object" and "this object has an interface to that object").
:stylin: "Make games, not war.""...if you're doing this to learn then just study a modern C++ compiler's implementation." -snk_kid

This topic is closed to new replies.

Advertisement