Archived

This topic is now archived and is closed to further replies.

wah_on_2

multi-inheritance problem

Recommended Posts

i have 4 classes
  
class CCharacter{
....
virtual bool SelectedMe(.....) = 0;
}

class CNormalChar : public virtual CCharacter{
....
bool SelectedMe(.....){//implemented...};

}

class CBattleChar : public virtual CCharacter{
....
bool SelectedMe(.....){//implemented...};

}

class CHero: public CBattleChar, public CNormalChar{
.....}
  
the implementation method in CBattleChar is differ with CNormalChar. How can i solve it? Compile error: CHero:ambiguous inheritance of CBattleChar::SelectedMe CHero:ambiguous inheritance of CNormalChar::SelectedMe Also, why this error occur? Thank You!

Share this post


Link to post
Share on other sites
How do you want SelectedMe implemented in CHero?

One way to solve it is to write a wrapper in CHero that specifies which of the parent methods to call:

bool CHero::SelectedMe( ... )
{
return CBattleChar::SelectedMe( ... );
}


Other than that, you need to refactor your design.

As to why the error occurs, classes with virtual methods are built for inheritance and posses a structure commonly referred to as a vtable to facilitate this. The vtable - or virtual function pointer table - is filled in with the addresses of concrete functions when an instance of a virtual class (including its derived classes) is created. In this case, however, it is impossible to determine which of the parent classes'' function should fill the vtable. This is one of the disadvantages of diamond inheritance (where both parents of a class are derived from a common base).

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
Thank you your explaination.

In fact, I want to do the following.

CCharacter<--(inherit from)CBattleChar<--(inherit from)CEnemy
CCharacter<--(inherit from)CNormalChar<--(inherit from)CNpc
CBattleChar & CNormalChar<--(inherit from)CHero

1.)CBattleChar is related to battle(e.g contain attack, defense methods) only. CNormalChar is related to map(e.g. move method) only. So CEnemy is a battle character, it will not do anything relate to map. Also CNpc is similar.

2.)CHero is related to map and battle, so i make it multi-inheritance.(please correct me if it is wrong)

3.)Both of them can selected by player.(e.g select npc for talk, select enemy for attack). However, the implementation mehtod of them are different, i implement it on the CBattleChar and CNormalChar.

if the compile is impossible to determine which of the parent classes function should be call. So how can i correct it?

I don''t know multi-inheritance will cause problem, can give me some website that talk multi-inheritance? Thanks

Share this post


Link to post
Share on other sites
quote:
Original post by wah_on_2
if the compile is impossible to determine which of the parent classes function should be call. So how can i correct it?

See my previous answer. You need to implement the method in your derived class and then explicitly state which parent''s method to call.

quote:
I don''t know multi-inheritance will cause problem, can give me some website that talk multi-inheritance? Thanks

Not off the top of my head, sorry.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
I have an idea but i don''t know is it correct.

To prevent diamond multi-inheritance cause problems. i can just implemet all the abstract methods in the sub class only.

e.g i have a abstract method call

virtual void test() = 0; //in CCharacter

then i also implement it in CNpc, CEnemy and CHero, although i can implement it CBattleChar and CNormalChar

void test(){};

Can i solve the problem: compile is impossible to determine which of the parent classes function should be call.

Share this post


Link to post
Share on other sites
A new design is needed.

Read about "Design Patterns".
You need to replace inheritance with aggregation.
Use the "chain-of-command" and/or "template" design patterns.


It''s easy to misuse inheritence

  
class Bird
{
virtual void Eat()=0;
virtual void Sleep()=0;
virtual void Fly()=0;
};

class Hawk : public Bird
{
virtual void StalkPrey()=0;
};

class Chicken : public Bird
{
virtual void LayEgg()=0;
};

class Penguin : public Bird //Logic Error!

{
//Penguin cannot fly!!!

virtual void Swim()=0;
};


You have a similar problem.

Share this post


Link to post
Share on other sites