• Advertisement
Sign in to follow this  

inheritage with classes

This topic is 1236 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all.

 

I'm currently working with rendering in my program and I got a small problem. I need to layer my art resources dynamically as the players moves through the map so the depth of my game make a little more sense. I've thought about how I could do this and a child class seems to be my solution.  The scenario I'm put in is that I have 2 classes that have a function called 'show' and they basically print the art resources on screen. I call the function "show" twice in my main function to render the level, one class function shows the character and the other class  function shows the tiles.  

 

What I want to do is make a child class that inherit from both classes so I can have a child class function print all of the art resource in my "int main (int arc, char* args[])" with certain modification. I'm trying my best but I still don't it. This is where I'm learning http://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Inheritance

 

If you know a better website to grasp this knowledge please link me or post a simpler homemade example.

Share this post


Link to post
Share on other sites
Advertisement

Wrapping your head around inheritance (and in your case, polymorphism) is one of the keys to excellent software architecture. There are a lot of good tutorials online explaining inheritance (see

 

The short of it, is you need a parent class that defines the show function, and you need a way to enforce that children classes implement that function.

// Parent class
class ArtRenderer {
   // The = 0 makes the class abstract, which means that child classes MUST implement this function. This makes the c++ class similar to a java interface
   public:
      virtual void show() = 0;
};

Two things now happen for any class that inherits from ArtRenderer. First, they must implement the show() function. Second, they can be referred to within code as ArtRenderer objects.

class Map : public ArtRenderer {
   // Add any Map specific variables/methods

   public:
      void show(); // Here we implement the show method defined by ArtRenderer
}

class Player : public ArtRenderer {
// Add any Player specific variables/methods

public:
void show(); // Here we implement the show method defined by ArtRenderer
};

Now for the magic of polymorphism. As I said above, your child classes can be referred to as ArtRenderers throughout your code. This is because the child classes support the Is-A relationship. So within your main (or other control logic function), you would do:

int main() {

   Map *map = new Map();
   Player *player = new Player();

   // This assumes some type of List data structure to store ArtRenderer objects, such as in stl libraries. 
   List<ArtRenderer> *renderedObjectsList = new List<ArtRenderer>;

   // Because the Map and Player objects are also ArtRenderer objects, any pointer to an ArtRenderer can be used to point to your Map or Player objects. This concept is known as polymorphism
   renderedObjectsList->add(map);
   renderedObjectsList->add(player);

   // Now loop over the objects in the list and call the show method
   for each object renderedObject in renderedObjectList {
      // This will actually call the child class show implementation!
      renderedObject->show();
   }
}

Voila! Using a parent class to define and call a common function from child classes.

Share this post


Link to post
Share on other sites

Hmmmm This doesn't seems to be what I'm trying to do. I need the child class to do more than print, I need it to print in a specific way.

can child class can inherit from 2 parent classes?

Share this post


Link to post
Share on other sites

Wrapping your head around inheritance (and in your case, polymorphism) is one of the keys to excellent software architecture.


Particularly, the part where you shouldn't use it when you have other options.

LAURENT doesn't need a subclass. LAURENT needs to learn data-driven design practices.

The desired result can be achieved with a non-polymorphic Sprite/Mesh class that uses the data in its member variables to determine what specifically it renders, which layer(s) it renders on, etc.

Use code to define _mechanism_ (how something is done) and data to define _policy_ (what should be done). The "how" in this case is "draw stuff" and the "what" is "image, layer, animation frame, etc."

In the event that you have some drastically different mechanisms to rendering (e.g. if a map is rendered very differently from a player) then have two separate lists, e.g.:

struct Renderables {
  vector<MapRenderable> maps;
  vector<SpriteRenderable> sprites;
};

// alternative if layering is a big deal

struct Renderables {
  struct Layer {
    vector<MapRenderable> maps;
    vector<SpriteRenderable> sprites;
  };

  vector<Layer> layers;
};
Data defines what goes into those containers and what properties they have. The code just knows how to render maps and sprites. Things like which layer they are rendered on are controlled by the data. How layers are rendered and composed is controlled by code. Pure separation of mechanism and policy.

Not only is this code (arguably) better structured, and not only is it shorter/simpler than inheritance boilerplate mandates, and not only does it avoid the lifetime and management issues that plague polymorphic types, and not only is more control given to your designers and artists, but it's also potentially much faster to execute as well (polymorphism and virtual functions are best avoided in any tight loops, like render loops, when possible).

Use the 'virtual' keyword very sparingly and only when you're completely sure that you really really need polymorphism and type erasure. Once you downplay the use of 'virtual' you'll also find that type hierarchies in general are often unnecessary.

can child class can inherit from 2 parent classes?


In C++, yes, but is an especially troublesome use of inheritance. Don't do it without a very good reason (and if you're not an expert in the language yet, you never have good reason).

Share this post


Link to post
Share on other sites

You're trying to avoid writing 2 or more consecutive lines calling the "show" methods for different objects? Maybe you can use Interfaces instead of classes.

 

Define an interface called "showable" ("drawable" sounds better) and make every class that models an object the will be shown (drawn) implement that interface. Then, in some place define a list of "showable" (or drawable) objects, and iterate over that list calling "show" on each one when you want to display them. Each "show" will work different for each class, so you can have really different functionality, but you only have 1 line for calling the show method.

Edited by DiegoSLTS

Share this post


Link to post
Share on other sites

... I'm overwhelmed. 

 

Hey guys you don't know how I'm doing this. What I mean is generating the levels and printing. The solutions seems a bit too radical to implement at this stage of my project. I understand there are controversial topics regarding certain data structure but at this point it's too far gone. Inheritage is my focus for now.

 

I've done some testing a while ago with one class to see how I would like to do my layering. It was successful but there were other problem with my code at the time. I have done some thinking and I have an idea of what I need.

 

I need a way to get stuff from my classes so I can use them. From "Class A" I need variables specifically the X and Y variables that determine my character's location on the map.  The X and Y variables are private and are defined in the constructor of "Class A". These variables values are manipulated by Class A functions. From Class B I need the constructor. It's used to determine the location of the block tiles on the map as well as give them collision boxes.

Share this post


Link to post
Share on other sites


Inheritage is my focus for now.
Problem is this specific use case is not a good use of inheritance.

Inheritance would be for example: base class Platform always draws. Derived class PhantomPlatform draws only if ... seconds till start of the level /2 is odd.

 

What's the point with those classes A and B?

For the purpose of the original problem, class A just needs to have (x,y,layer) instead of (x,y).

 

If class B is a factory of some sort generating instances of class A, then yes, it needs the ctor. Otherwise... I cannot make much sense of what you're trying to tell us.

Share this post


Link to post
Share on other sites

Please give a more thorough description of the situation and what are you exactly trying to achieve.

 

Currently I feel you are just trying to work around some arbitrary restrictions that you have accidentally placed on yourself by taking the one route that somehow happens to avoid them, when in the long term it would probably be better to go and rethink class A and class B, maybe splitting some functionality, merging other functionality or just exposing their internals a bit more so you can access them without inheritance.

 

But I dont know because Im not sure what you are trying to do.

Share this post


Link to post
Share on other sites

... I'm overwhelmed. 

 

Hey guys you don't know how I'm doing this. What I mean is generating the levels and printing. The solutions seems a bit too radical to implement at this stage of my project. I understand there are controversial topics regarding certain data structure but at this point it's too far gone. Inheritage is my focus for now.

 

I've done some testing a while ago with one class to see how I would like to do my layering. It was successful but there were other problem with my code at the time. I have done some thinking and I have an idea of what I need.

 

I need a way to get stuff from my classes so I can use them. From "Class A" I need variables specifically the X and Y variables that determine my character's location on the map.  The X and Y variables are private and are defined in the constructor of "Class A". These variables values are manipulated by Class A functions. From Class B I need the constructor. It's used to determine the location of the block tiles on the map as well as give them collision boxes.

What you're trying to do (multiple inheritance) can only be done in certain languages and it's a clear case of a code smell if you need it that much, so any answer using it will probably create more problems in the future.

 

This is the moment where you should change the architecture if you found that the current one can't do what you need. It will be harder to change it later because you'll have hacks in different parts to make things work.

 

Also, inheritance is not a concept you should use by it's own. If you're doing OOP you must consider the other concepts too, they exists for a reason, there are cases where the rest of the concepts just can't (or shouldn't) be applied.

Share this post


Link to post
Share on other sites

I'm not completely sure you guys know what I want so I can't just try any solution without question. We need to work toward the same goal and if I misworded anything I could be given advice that could throw my entire project into chaos. I have to make sure I protect myself in case of miscommunication.

 

 

 


 Inheritage is my focus for now.
Problem is this specific use case is not a good use of inheritance.

Inheritance would be for example: base class Platform always draws. Derived class PhantomPlatform draws only if ... seconds till start of the level /2 is odd.

 

What's the point with those classes A and B?

For the purpose of the original problem, class A just needs to have (x,y,layer) instead of (x,y).

 

If class B is a factory of some sort generating instances of class A, then yes, it needs the ctor. Otherwise... I cannot make much sense of what you're trying to tell us.

 

 

 


Inheritage is my focus for now.
Problem is this specific use case is not a good use of inheritance.

Inheritance would be for example: base class Platform always draws. Derived class PhantomPlatform draws only if ... seconds till start of the level /2 is odd.

 

What's the point with those classes A and B?

For the purpose of the original problem, class A just needs to have (x,y,layer) instead of (x,y).

 

If class B is a factory of some sort generating instances of class A, then yes, it needs the ctor. Otherwise... I cannot make much sense of what you're trying to tell us.

 

 

Class A and Class B do their own thing by themselves. They have a peer to peer relationship as I was told. Class A moves the character/ handles button input/ and print the character on screen. Class B prints tiles on screen. Everything has a collision box. Printing is done by calling a global function called "apply_surface(x,y, ect)" within each class function call "show()". Both classes have a function named "show" that calls "apply_surface()" to print. Within in the main function I call "show" for the respected classes.

Edited by LAURENT*

Share this post


Link to post
Share on other sites

If I understand correctly, you want an object that has a method `show' which will call `show' on both the character and the tiles. You can do that by having a simple class with references or pointers to the character and the tiles and whose `show' method calls the `show' method for the character and the `show' method for the tiles.

 

If you want to make your class more general, so you can give it any number of things to call `show' on, you can do that by using inheritance and polymorphism. You make a class (or interface) called Showable, from which both the character and the tiles inherit. You can then have an object that has a container of Showables and whose `show' method calls the `show' methods on all the objects it contains. That would be a much more natural use of inheritance.

Share this post


Link to post
Share on other sites

If I understood correctly, you have the following procedures:

-Show character

-Show all the tiles

 

But you need:

-Show all the tiles and the character

 

To handle depth sorting.

 

A flexible solution would be to add a new depth sorting layer between the two classes you have and the actual rendering. So each class issues 'render requests' for tiles/character that includes the depth information (as in depthSortingRenderer.addSurface(x,y,depth, etc...) ), and then at the very end you sort them by depth and render them to screen in order.

 

Another approach would be to write up a new procedure that can render both tiles and characters in one go, but I couldnt decide where the logical place for that would be. Inheriting from both character and tile renderer is not it (its neither a tile renderer nor a character!). Inheriting from the tile renderer doesnt really keep it as a tile renderer anymore. Maybe you could modify the tile renderer so it renders a single layer at a time (tileRenderer.showLayer(N)) which would allow you to throw the character rendering in the right spot? Or anything like that (like .showAllTilesBetweenDepths(mindepth,maxdepth), or .renderAllTilesButCallThisCallbackJustBeforeRenderingThisDepth(callback lambda func,depth) so you can draw the character in the callback)

 

Dont really program much at all so not very good at code structuring issues :P

Share this post


Link to post
Share on other sites

If I understand correctly, you want an object that has a method `show' which will call `show' on both the character and the tiles. You can do that by having a simple class with references or pointers to the character and the tiles and whose `show' method calls the `show' method for the character and the `show' method for the tiles.

 

If you want to make your class more general, so you can give it any number of things to call `show' on, you can do that by using inheritance and polymorphism. You make a class (or interface) called Showable, from which both the character and the tiles inherit. You can then have an object that has a container of Showables and whose `show' method calls the `show' methods on all the objects it contains. That would be a much more natural use of inheritance.

 

I made a class call render which is inherited by Class A and Class B. I moved all the private variables from both class to the Render class and made them all protected. Am I getting closer to the solution? I didn't quite understand everything you said.

Share this post


Link to post
Share on other sites

I made a class call render which is inherited by Class A and Class B. I moved all the private variables from both class to the Render class and made them all protected. Am I getting closer to the solution? I didn't quite understand everything you said.


Nope. I'd argue that you're going in the complete wrong direction.

class A {
public:
  void render();
};

class B {
public:
  void render();
};

class C {
  A* a;
  B* b;

public:
  void render() {
    a->render();
    b->render();
  }
};
Absolutely no inheritance is needed.

Prefer _aggregation_ over _inheritance_ (C in this case "aggregates" A and B, but does not inherit from either of them, nor do they inherit from C).

In general, use inheritance when you need _is-a_ semantics. E.g., Derived _is a_ Base. Otherwise, use a _has-a_ relationship, e.g. Composite _has a_ Component. This even works for shared functionality. If A and B both have the same renderable methods and data you can move those off to a RenderHelper type and then include that as a member in A and B rather than inheriting from it. Then you can also add even more helpers to A and B without ending up down the rat hole that is multiple inheritance.

Share this post


Link to post
Share on other sites

Hmmmm This doesn't seems to be what I'm trying to do. I need the child class to do more than print, I need it to print in a specific way.

can child class can inherit from 2 parent classes?

 

It seems you have decided to implement things a different way, but in my example each child class would be responsible for defining the specific way that class should print. The ArtRenderer class only defines the functions the child classes are required to implement (in this case, the show() method). The specifics of how each child class implements the show method is not restricted in any way. One class could render things as ASCII art, and the other through OpenGL. But, after reading through your additional posts, inheritance isn't really needed to solve your problem.

 

@SeanMiddleditch

Aggregation is fine until you have lots of different classes that all have to implement a show function. In your example, with aggregation alone you would have:

class A {
public:
   void render();
};

class B {
public:
   void render();
};

class C {
public:
   void render();
};

class C {
public:
void render();
};

class D {
public:
void render();
};

class E {
public:
void render();
};

class F {
A* a;
B* b;
C* c;
D* d;
E* e;
// and so on

public:
void render() {
a->render();
b->render();
c->render();
d->render();
e->render();
// and so on
}
};

It's pretty concise if anything that can be rendered implements a Renderable interface. Then anytime you need to hold several Renderable objects, you can just refer to them through the interface type. For example, you can then store all of your Renderable objects in a data structure (e.g. maybe you want to keep things in a tree to optimize collision detection) - which essentially aggregates all of the objects. Saves you from having to deal with the ugliness of templates.

 

Regardless, can you post some links to data-driven programming tutorials? It's useful stuff to know about.

Share this post


Link to post
Share on other sites

I do not need inheritage. It would be nice if I did since it would fulfill another  personal quota for the project but I do not need it.

 

Never ever ever ever ever ever use a programming pattern just to use it.  Most of the time you will be making the wrong decision.  Code should evolve from your needs, not the other way around.

Share this post


Link to post
Share on other sites

 

I do not need inheritage. It would be nice if I did since it would fulfill another  personal quota for the project but I do not need it.

 

Never ever ever ever ever ever use a programming pattern just to use it.  Most of the time you will be making the wrong decision.  Code should evolve from your needs, not the other way around.

 

Oh yeah! Answer me this, how do I know when I need it?

Share this post


Link to post
Share on other sites

Oh yeah! Answer me this, how do I know when I need it?


Don't worry about it. One day you'll be staring at some problem and you'll realize inheritance ("inheritage" is not a word) is precisely what you need to solve it. If that day never comes, maybe inheritance wasn't important to begin with.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement