c++; inheritence; multiple? or perhaps a better solution?

I think maybe I'm going about my coding needs the wrong way, but I'm kind of in a rut and cannot seem to think outside the box at the moment. Perhaps someone could either help me to fix my code or suggest a better alternative? I'd really appreciate some aide.

I have a base class, ABase. This class has a map<string,string>* parameter, and a few others, too. This base class handles the setting/getting of the other parameters, and only generic access to the map (i.e. it gets a list of all keys, gets a list of all values, etc).

Next, I define a derived class, ABaseCore, which targets specific key names to be used in the ABase->attrs. It doesn't add any new parameters, it simply provides a convenient set of methods for setting/getting some parameters I consider core attributes.

Then, I define another derived class ABaseExtra, which does pretty much the same thing as ABaseCore, but different named methods for specific parameters.

There are about 3 or 4 other derived classes, which all have their own unique methods for handling specific parameters. I'll skip the code on those, since they are pretty much the same thing as ABaseCore and ABaseExtra.

Now, the intent is to derive new classes from several of the previously derived classes (such as ABaseCore) - this is so my new classes have a nice collection of convenient-to-use method names which target the specific parameters.

Now, I understand the dynamics of referring to the base class in an unambiguous way. part of the problem, however, is that I want the base class to have an overloaded operator<< which will output any of the higher level derived classes (such as ABC and DEF), but I can't quite figure out how to make it work. I keep getting the error:

ambiguous conversions from 'ABC' to 'ABase &'

on the code:
ABC *a = new ABC();

cout << (*a) << endl;

I have a feeling there is a better way to accomplish what I'm trying to do, but I've been staring at this code for about an hour and I think my brain will implode soon.

I could simply forgo the 2nd-level of derivation, and simply put all the methods (from ABaseCore, etc) right into ABC, etc... but that would be a lot of duplicate code... not every derived class will require the ABaseCore methods and not every derived class will require the ABaseExtra, but enough do that having a re-usable code segment makes sense.

link64: It won't work like that, simply due to the fact that ABase and ABC are not directly linked. Now, I could say:

ABaseCore *abc = new ABC();

and that would work... but then I lose the functionality of not only the other inherited classes (ABaseExtra, etc) but also the ABC-specific methods. It is a good thought, though.

jhshukla: That does answer the basic question of, how does one access the base members in an inherited class, especially one who has multiple levels of inheritence. However, the problem of ambiguity still remains. Supposing the ABase class contains a method "add(string text)"... ABaseCore and ABaseExtra both inherit this method from ABase. And now ABC inherits both ABaseCore and ABaseExtra, which has thus inherited two different sets of ABase. As a result, ABC now contains two different inherited "add(string text)" methods.

Subsequent calls to the "add()" method on ABC have to know which sub-ABase is being referenced.

I could say something like:

ABC *abc = new ABC();
abc->ABaseCore::add("blah");

This does work. But, supposing class GHI does not inherit ABaseCore, but ABaseExtra? But now I have to remember to say:

ghi->ABaseExtra::add("blah");

This is fine, except that it defeats the whole purpose of inheriting. The point is to provide a common support structure, a foundation, which provides the most basic methods required to make the inheritors, and I (as the programmer) don't need to worry about which class inherits what, at least for the basic stuff.

I hope this makes sense.

I know that java doesn't allow multi-inheritance and probably for these very kind of issues. :)

I would like to add that I'm not even saying the way I'm doing this is correct. If there is a more eloquent solution, I'd be happy to consider it.. and, and I bumped the points up to the max, in the hopes that a solution can be found. In the meantime, I'll continue tinkering with the code. :)

You always should be aware that any public derivation is an "IS A" relation, e. g. for an ABC object it should be correct to say "it is an ABase", "it is an ABaseCore" and "it is an ABaseExtra". If one of these statements is not quite true, it would be better you define all functions virtually in ABase and derive only from one of ABaseCore or ABaseExtra (or from ABase directly) and reimplement the functions again.

0

BaconUAuthor Commented: 2008-10-15

itsme: I admit the "virtual" keyword gives me a little confusion in the cranial area.

After first testing the example given by you, the ambiguity was not resolved when calling methods from ABC defined in ABase. However, when I changed the ABaseCore definition to:

class ABaseCore : virtual public ABase

.. and the same for the other classes derived directly from ABase, now it does not complain about ambiguity.

So, it looks like the solution! Yay! I will of course do some reading up and research on the virtual keyword so that I may utilize it appropriately. :)

Thanks!

0

BaconUAuthor Commented: 2008-10-15

As I noted in my comment to the thread, the 'virtual' keyword needed to be placed on the first derivation of ABase. This seems to have solved the ambiguity.

The compiler needs to know that for the ABaseCore part and the ABaseExtra part used in ABC it should use only one part of ABase. Hence it needs the virtual keyword where the relation to ABase was defined.

In memory you would have

[ABase members][ABaseCore members][ABC members]
[ABaseExtra members]

ABC, ABaseCore, ABase (normally) share the same pointer, while the ABaseExtra has a different pointer.