Inheritance is a pain help please

Started by
15 comments, last by Whoknewb 21 years, 4 months ago
Ok I really do understand the idea''s of Inheritance, but I just don''t really know how to implement it. Please help me, this has been giving me a serious pain in the butt for the longest time. All my designs i use to solve problems usually have a HASA relation ship(because I make them) It''s easy to make a class like a data type, and use the data type as a member in the class, but inheriting a class from some base scares me, I''m not sure what it will do exactly. Also I''m stuck on polymorphism I''m not too sure how virtual works, ok I understand the concept that you use virtual if you plan on overriding(or overloading I forget) the method, but does a virtual method also get inherited by the base class? I''m trying not to specify my questions to much, because I need help understanding how exactly derived classes inherit the base class methods, and i''m not sure how to phrase my question. Any inheritance/polymorphism guru''s out there please lend me a hand.
Advertisement
Ok here are some examples of how i use inheritence and polymorphism in my current game project...

Game States - My program has 3 states it can be in, MainMenu, OptionMenu, and Game. I created a base class called State. State was given the pure virtual functions Init(), Update(), Render(), and Shutdown(). Now I created 3 more classes, each inheriting from the State class. These 3 classes are MainState, OptionState, and GameState. They all inherit the virtual functions listed above, but these functions need to be implimented since they are pure virtual (contain nothing). Ok so now my main application had 1 MainState, 1 OptionState, and 1 GameState. I then create a pointer to a State object (the base class). This pointer will point to whichever state the application is in, and call the states init, update, render, and shutdown functions. If the state changes then i just point the pointer to the next state i want to be in and call those functions instead (polymorphism).

Ok that was a bit hard to explain and may not be clear, so another example...
Say i have some enemies, Orcs and Trolls. I want to store ALL my enemies in one list. I could create a cEnemy class that stores the location on the map, and has the members Draw() and Move(). Now i create my class Orc : public cEnemy and class Troll : public cEnemy. I can now create a list that hold cEnemy objects and fill it with trolls and orcs. Then I go through the list and call the cEnemy->Draw() functions for each object. If it is an orc then the orc draw() is done if it is a troll then the troll draw() is done. This is polymorphism.

Basicly when you declare a function to be virtual that means that the classes inheriting those functions can re-impliment them to do their own thang. There is much more that can be tossed in to confuse the fact like calling the base class virtual function from an inherited class, but we wont go into that as it is not needed in my examples and ::''s scare me when they travel in groups.

I hope this is somewhat clear...
quote:Original post by Whoknewb
Ok I really do understand the idea''s of Inheritance, but I just don''t really know how to implement it.

Please help me, this has been giving me a serious pain in the butt for the longest time. All my designs i use to solve problems usually have a HASA relation ship(because I make them) It''s easy to make a class like a data type, and use the data type as a member in the class, but inheriting a class from some base scares me, I''m not sure what it will do exactly.

Also I''m stuck on polymorphism I''m not too sure how virtual works, ok I understand the concept that you use virtual if you plan on overriding(or overloading I forget) the method, but does a virtual method also get inherited by the base class?

I''m trying not to specify my questions to much, because I need help understanding how exactly derived classes inherit the base class methods, and i''m not sure how to phrase my question.

Any inheritance/polymorphism guru''s out there please lend me a hand.


If you make a function virtual in the base class your are saying I am going to redefine it someother time. So all your derived classes will inherit that function as is until you change that function. Now I am not sure but think if you have a base class with a virtual function and two derived classes, one with the virtual function redefined and you inherit that class the derived class from the first derived class will have the virtual function thats redefined. Don''t quote me but I think thats correct. =)
Here is a simple class with a dervied class

  class CBoxInt{private:int width;int height;int depth;int volume;public:CBoxInt(){width = 0;height = 0;depth = 0;volume = 0;}~CBoxInt(){}virtual void Calculate(int x, int y, int z){width = x;height = y;depth = z;volume = x * y * z;}virtual void Show(void){cout << volume << endl;}};class CBoxFloat : public CBoxInt{private:float width;float height;float depth;float volume;public:CBoxFloat(){width = 0.0f;height = 0.0f;depth = 0.0f;volume = 0.0f;}~CBoxFloat(){}virtual void Calculate(float x, float y, float z){width = x;height = y;depth = z;volume = x * y * z;}virtual void Show(void){cout << volume << endl;}};  


I know that example is bad you would use template()''s for that but that is all I could come up with to show inheritance off the top of my head. Hope that helps.
quote:
from illmind
Ok that was a bit hard to explain and may not be clear, so another example...
Say i have some enemies, Orcs and Trolls. I want to store ALL my enemies in one list. I could create a cEnemy class that stores the location on the map, and has the members Draw() and Move(). Now i create my class Orc : public cEnemy and class Troll : public cEnemy. I can now create a list that hold cEnemy objects and fill it with trolls and orcs. Then I go through the list and call the cEnemy->Draw() functions for each object. If it is an orc then the orc draw() is done if it is a troll then the troll draw() is done. This is polymorphism.


Ok I think that was a pretty good example, so help me out here. I made a game recently it was a breakout clone, and for every object it contained its own vertex buffer. I found out later that filling a vertexbuffer with only 4 vertices was a bad idea because switching between vb's is slow. So could i use polymorphism to fix this problem?

Like I would make a base object class that contained a vb, and each derived class would add it's vertices to that one vb in the base's member class? Would that work?

quote:
I then create a pointer to a State object (the base class). This pointer will point to whichever state the application is in, and call the states init, update, render, and shutdown functions. If the state changes then i just point the pointer to the next state i want to be in and call those functions instead (polymorphism).


Also how to do that? How do you have a pointer point to your base class if you havn't even instantiated the object yet?

class CDerived : public CBase;

CDerived d;

Now I'm using d, but how do I access the base class?

Also I think(though I do not know) that your strategy for implementing state changes is not needed. Why create a base class full of pure virtual methods. If each method needs to be defined in each of the derived classes, then your infact re-writing the code in each class. So it would be exactly the same to just make three different classes because they each define their own methods differently and do not inherit anything from your base State class.

Also if in your base class you new to allocate memory to member variables in your constructor and delete in your destructor, and in a derived class from it you overload the base class's destructor, what happens to the base class's destructor? Does it still delete the memory allocated?



[edited by - Whoknewb on December 5, 2002 3:41:36 AM]
quote:
Also how to do that? How do you have a pointer point to your base class if you havn''t even instantiated the object yet?


CBase *cbase = new CBase();


quote:
class CDerived : public CBase;

CDerived d;

Now I''m using d, but how do I access the base class?


CBase cbase = CBase();
CDerived d = CDerived();

d.whatever();
cbase.someother();




Signatures are lame!! =)
quote:Original post by Whoknewb
Also I'm stuck on polymorphism I'm not too sure how virtual works

Virtual states that a function will be despatched based on the dynamic type of the object it is invoked upon. What's that mean in English? Let's say you have some code which follows this basic pattern:
class Base{public:  virtual foo();  virtual ~Base() {}};class Derived : public Base{public:  foo();  // override of Base::foo};   

Now, let's say you have some code which creates an object and calls foo, like this:
Base *obj = new Derived;obj->foo();   

"obj" is a pointer to an object. The pointer's static type is of type "Base". However, the dynamic type of the object (the type that is "newed") is "Derived".

Digression: whenever you use public derivation, you are modelling an IS-A relationship, and it's that which allows you to assign a Derived pointer to a Base pointer. You are saying "a Derived IS-A Base, so I must be able to use a Derived wherever a Base is expected".

So, in the above code, "foo" is marked as being virtual. I said above that virtual means the function will get despatched on the dynamic type of the object. Since the dynamic type is "Derived", then the actual function call gets resolved to Derived::Foo - the compiler decides at runtime what type of object "obj" really points at. Try it in your debugger. So, if virtual means "dynamic despatch", then non-virtual means "static despatch". If foo wasn't marked as virtual, it would be Base::Foo that got called. Try that in your debugger too.
quote:
does a virtual method also get inherited by the base class?

You mean by the derived class? Yes. There are two reasons for inheritance: interface inheritance and implementation inheritance. Interface inheritance means that you are deriving an object because you want to have the same public member functions. If two classes have all the same public member functions, then a user of those classes doesn't need to know that the objects are actually different, and can treat them in the same way. Implementation inheritance means that you inherit the implemented behaviour of the class.

So, what's "polymorphism" mean? A definition might be expressions having the same syntax can be applied over different types of entities and produce distinct behaviour for each type . In this context, polymorphism is achieved via a combination of interface inheritance and dynamic despatch. Imagine you have this code:
class GameObject{public:  virtual attack();  virtual ~GameObject() {}  // other functions...};class Infantry : public GameObject{public:  attack()  {    // code to fire a rifle  }};class Tank : public GameObject{public:  attack()  {    // code to fire a shell  }};   

We know that both Infantry and Tank can attack things, but there's obviously a difference in the way they do that. So, we model that difference by overriding the attack member function in each class. Now, imagine in your game that you maintain a list of all the GameObjects, and every turn each object gets a chance to attack. Here's some more code to illustrate:
list<GameObject*> game_list;game_list.push_back(new Infantry);game_list.push_back(new Infantry);game_list.push_back(new Tank);   

As I already explained, if you make pointer to GameObject the element type of game_list, you can assign pointers to derived objects (IS-A). When it comes to the attack phase of your game, you do this:
list<GameObject*>::iterator it = game_list.begin();for(; it != game_list.end(); ++it)  (*it)->attack();   

Here, you use the same syntax to call the attack function, regardless of whether the object is a Tank or Infantry. That's because they have the same interface (interface inheritance). And, you know that the correct attack function will get callled according to the type of object, because you marked attack as virtual in the common base class (dynamic despatch).

You can add and delete objects in game_list as the game progresses, and no matter what type of object you add, as long as it is derived from GameObject, the code for the attack phase never needs to change. Now go back and read the earlier definition of polymorphism that I provided. Do you see what it means?

Edit: whoops!

[edited by - SabreMan on December 5, 2002 11:48:24 AM]
I must say SabreMan you are very knowledgable.

Ok a few questions.

When you publicly inherit from a base class, do you inherit it''s private variable members? Or just the protected variable members of the base class. Also if you do inherit the member variables does each instance of the derived class get it''s own copy or by modifying the derived class''s inherited members not only modify itself, but also the base class and any other class that inherits those members?

Also another question is still unanswered. Say if I am able to inherit private(or protected?) member variables. Let''s suppose that the base class allocates memory via new to it''s member variables, and the destructor dellocates memory. If I override the class''s virtual destructor because I need to delocate my own memory in my inherited class, does that cause a memory leak because the base class''s destuctor was not able to delete the membor variables?

In an implementation inheritance it is used to have the same type with different behaviors, but interface is used to reduce code bloat by inheriting methods that is commonly used by more then one class? Am I correct?

quote:
Now, let''s say you have some code which creates an object and calls foo, like this:

Base *obj = new Derived;obj->foo();

"obj" is a pointer to an object. The pointer''s static type is of type "Base". However, the dynamic type of the object (the type that is "newed") is "Derived".


So your saying the only way to use the obj''s foo''s method is put it in dynamic memory?

thanks for the help people
quote:Original post by Whoknewb
When you publicly inherit from a base class, do you inherit it''s private variable members?

Yes. You inherit everything. Only, you can''t access the private members because they''re private to the base class. So, they are there, but you can''t get at ''em.
quote:
Also if you do inherit the member variables does each instance of the derived class get it''s own copy or by modifying the derived class''s inherited members not only modify itself, but also the base class and any other class that inherits those members?

Look at it this way. The entire base class becomes a part of the derived class. The derived *is a* base class plus some. So, no, the derived class doesn''t create a new copy of the members.
quote:
Also another question is still unanswered. Say if I am able to inherit private(or protected?) member variables. Let''s suppose that the base class allocates memory via new to it''s member variables, and the destructor dellocates memory. If I override the class''s virtual destructor because I need to delocate my own memory in my inherited class, does that cause a memory leak because the base class''s destuctor was not able to delete the membor variables?

No. You''re not able to override base class constructors and destructors - they''re not really functions, they just look like they are. When you construct a derived class, it will be initialised in the order: base, members, derived. It will be destructed in reverse order. The base class constructor and destructor will *always* be run. Be careful though. If you delete a pointer to a derived via a pointer to base, you must have declare the base destructor to be virtual, else what will happen is undefined.
quote:
In an implementation inheritance it is used to have the same type with different behaviors

Implementation inheritance is a bit like a code reuse mechanism. It''s like saying "well, I''ve already implemented that function in the base class and I''d like to use the same implementation in the derived, so I''ll inherit". However, public inheritance is not good enough for that alone, since it serves the dual purpose of implementation *and* interface inheritance. If you only want implementation, you should use containment or maybe private inheritance.
quote:
but interface is used to reduce code bloat by inheriting methods that is commonly used by more then one class?

It has nothing to do with code bloat. In fact, having read that, I think you have interface and implementation the wrong way around. Swap them, and you''re pretty much there.
quote:
So your saying the only way to use the obj''s foo''s method is put it in dynamic memory?

No. To achieve dynamic despatch, you have to access the object through a pointer or a reference. You don''t *have to* new the object to get that, it was just easiest for demonstration. If you do use new, don''t forget to delete, and don''t forget the virtual dtor in the base class!
I don''t think anybody explained this:


  class CBase = {public: int eat(); int sleep();  ~CBase();}CBase::Sleep(){ cout << "SNORE";}class CDerived : public CBase{public:int foo();~CDerived();}CDerived::Foo(){ cout << "FOO!!";}  


when you do that you can then:

CClass = new CDerived;CClass.Sleep() 


that will put "SNORE" onto the screen.


Maybe I''m thick header but I''m not exactly getting this.

quote:
No. You''re not able to override base class constructors and destructors - they''re not really functions

what? I''ve heard that you should always make constructors/destructors virtual if you plan on ever deriving a class from it. What is the point of making a constructor/destructor virtual if you''re going to use the base and derived class''s destructors and not inherit the base''s destructor?

Ok. After re-reading what you said about interface/implementation your right I do have it backwards.

Also, why do you do CBase *pDerived = new CDerived; ?
As the AP pointed out you can just do
CDerived *pDerived = new CDerived;
and that will inherit all of CBase''s method''s the exact same way. I don''t understand the difference between those two statements.

This topic is closed to new replies.

Advertisement