How to 'set' object to a particular base class in multiple inheritence? - c++

I'm trying to inherit from two base classes in C++, that have same named functions. I want an object of the class to 'belong' to the particular base class, is it possible to do so?
I have tried virtual base class (does not suit my particular case) and also tried using scope resolution operator with failure.
I want to do this just by using a single class if it's possible.
I have provide the code;
#include <SFML\Graphics.hpp>
class entity :public sf::CircleShape, public sf::RectangleShape {
public:
entity(int radius = 0) { setRadius(radius); }
entity(sf::Vector2f size) { setSize(size); }
float xspeed =0, yspeed =0;
};
entity ball(6);
entity block(10, 10);
window.draw(block); // ambiguity error as both have base class sf::drawable
window.draw(ball); // and draw function accepts sf::drawable
The problem is that I want "ball" just to inherit from sf::CircleShape and not from sf::RectangleShape.
I expected using scope resolution operator would refer to the circleshape class or I might just be using it wrong.
Edit: The problem I'm trying to solve is that I want to draw "ball" and a rectangular block on to the window, and when I try to do that I'm presented with an ambiguity error as they both are drawable (i.e. both sf::RectangleShape and sf::CircleShape inherit from sf::drawable)
Edit(2): The inheritence diagram
So the function window.draw(); accepts any object of sf::drawable as a parameter. But as I inherit both circleshape and rectangle shape to entity I get an ambiguity error saying base class is ambiguous.
I know this is diamond of death situation however using virtual base classes is not possible as they are part of the SFML library and I do not want to modify them

Problem analysis
class entity :public sf::CircleShape, public sf::RectangleShape
This declaration says that every entity is simultaneously a CircleShape and a RectangleShape. This does not seem to be what you want. You seem to want an entity that can be either a circle or a rectangle. So this inheritance is not the right strategy.
Given that you are adding horizontal and vertical speeds, it seems like you are trying to add a basic animation to elements that can be drawn. Animation is an abstract concept that builds upon drawing (an animation must be drawn, but not all drawings must be animated). Specific moving shapes would build on top of the animation, so your ideal inheritance would be more like the following:
circle -> entity -> drawable
However, there are a few drawbacks. One drawback is that this forces all circles to be animated entities, when some circles might simply be drawn in one spot. Plus, the circle and drawable classes are from a library, so you cannot mess with that particular inheritance scheme.
I can think of two reasonable alternatives off the top of my head. (By the way, "entity" is not a great name for your class, but I'll stick with it for consistency. You should come up with a more descriptive name for the class. It'll be good practice, as naming things is sometimes one of the hardest parts of writing code. :) )
Entity as a base class
You could define entity as a base class, then define a new class for each shape.
--> sf::CircleShape --> sf::Drawable
/
MyCircle --<
\
--> entity
This can work, but it is not great if entity needs to invoke functions defined in Drawable. Not impossible: a side-cast can make it possible to invoke Drawable's functions. It's just that you then have to account for the case where the side-cast fails, as the compiler cannot catch that.
Shapes as members
What I would probably do is give up inheritance altogether. Instead of trying to say that your entity is a circle (inheritance), I would go with the approach that your entity has a circle (membership). One benefit of this approach is that it is not hard to extend this to saying that your entity has multiple shapes, all moving at the same speed. I will, though, stick to a single shape for now.
The difficulty with this approach is that you don't know what shape the entity should have -- should it have a circle or a rectangle? Fortunately, this is the sort of thing polymorphism deals with nicely.
class entity {
std::unique_ptr<sf::Drawable> shape; // <-- Polymorphism to the rescue!
float xspeed = 0.0, yspeed = 0.0;
public:
// Construct a circle.
entity(int radius = 0) : shape(std::make_unique<sf::CircleShape>(radius)) {}
// Construct a rectangle.
entity(sf::Vector2f size) : shape(std::make_unique<sf::RectangleShape>(size)) {}
// Something will go here to support drawing.
};
To support drawing, there are (at least) two options. If it is appropriate to have an entity be a drop-in replacement for a Drawable, it might be reasonable to define an implicit conversion.
operator const sf::Drawable &() const { return *shape; }
If an implicit conversion is not desirable, marking it explicit is an option.
If the only time you need to use an entity as a Drawable is when you call window.draw(), you might want to instead give entity a draw method that takes window as a parameter.
void draw(sf::RenderTarget & target, sf::RenderStates states) const
{ target.draw(*shape, states); }
This makes the Drawable available to RenderTarget::draw() while keeping it out of sight (clutter reduction) at other times.

instead of using inheritance :
simply use direct association :
in your entity class, you want to have RectangleShape and CircleShape , so instead of making the entity class a CircleShape and a RectangeShape at the same time, it's better to consider your entity made of a CircleShape and a RectangleShape .this way you can in your entity class instantiate a RectangeShape and a CircleShape means 'entity' has a Rectangle and a CircleShape
it's the correct way to do it

Related

Getting derived member variable through base class pointer

consider this base class:
struct drawable
{
virtual void draw(sf::RenderWindow &window) const = 0;
};
and this derived class:
struct rectangle : drawable
{
rectangle(sf::Vector2f pos, sf::Vector2f size);
void draw(sf::RenderWindow &window) const;
sf::RectangleShape body;
};
I have similar derived classes for other shapes like circle, line and triangle. I use this function to return shapes based on a string of text I get from a file:
drawable * string_to_object(std::string name)
{
if (name == "RECTANGLE")
{
return new rectangle(sf::Vector2f(20,20), sf::Vector2f(5,5));
}
else if (name == "BALL")
{
return new ball(sf::Vector2f(10,10), 5, sf::Vector2f(0,0));
}
else if (name == "LINE")
{
return new line(sf::Vector2f(30,30), 10, 5);
}
}
Now in my main I have variables like this to test if it works:
auto game_object = string_to_object("BALL");
Now the problem is I need to perform actions/checks on the shape's body, which is a member of the derived class that I cannot access from the drawable pointer variables. It's also a problem that the type of the body is not set, it can be a RectangleShape, CircleShape etc so a getBody() function would need a variable return type. How would I go about getting access to the body in a generic way? I've tried templates but I realized that won't work since it's a runtime problem.
If I understand your question correctly, there are multiple ways how to solve this issue.
Re-think your architecture. You could introduce other virtual functions to drawable that every subclass implements. In these functions you'd implement all the checks/actions you need. Since they are implemented in the base class, they have access to the shape's body and since it is a virtual function of the base you can call these functions from the outside.
Since your drawable object has a virtual function, you could use RTTI to check the type at runtime and perform a dynamic_cast
See: https://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTI
I'd prefer the first option whenever you can.
It sounds like you're having trouble deciding what functionality is generic to all drawable objects, and what is specific to rectangle, ball and so on. Attributes and methods that apply to all drawable objects can be declared within drawable, but anything that only applies to a particular kind of drawable (like the width and height of rectangle vs. the radius of a ball) go in the derived classes.
In your example, each of the derived classes must implement the draw method if you want to instantiate them (because it is declared pure virtual in the base drawable class). Each of these specific derived implementations can access the specific attributes of the derived class. So the rectangle::draw method can access the width and height, while the ball::draw method can access the radius.
Then, when you have a collection of pointers to drawable objects (which are really instances of the derived classes) you can simply call the draw method for each of them.
Sorry if this seems overly simplistic - I hope it's clear.

Liskov Substitution Principle and class design for a game

In my game I have defined a Screen class, that contains references to a number of visual Entity objects, that may be drawn to the display:
class Screen {
public:
private:
std::vector<Entity*> entities_;
};
All Entity's, have a Draw() function:
class Entity {
public:
void Draw();
private:
int xpos;
int ypos;
};
The Screen is responsible for invoking the Draw() function on each of its Entitys.
The problem is that some (but not all) Entity's also need to be updateable, i.e. over time they will change their appearance/position. The Screen also needs to invoke an Update() function but only for those objects that are Updateable.
My question is:
Does it make sense to derive a class from Entity that has an Update function:
class ChangingEntity : public Entity {
public:
void Update(int time);
};
and have Screen look like this:
class Screen {
public:
private:
std::vector<Entity*> entities_;
std::vector<ChangingEntity*> changing_entities_;
};
If I do the above, then I invoke only Draw() for each of the Entitys, and Draw() and Update() on each of the ChangingEntitys.
Or - should I just put the Update() function in Entity, and if an Entity object can't update, then Update() has no implementation?
There are a couple of things you can enhance here;
It's better not to make the entity draw itself, use a separate Draw() function or Drawable class (Single Responsibility Principle). In your current approach you are making any class that needs drawing to extend Entity, next time you will figure out that a class doesn't need to be an entity to be drawable. So use a separate draw function .
Second you should define what an Entity is, Ogre3D for example define the Entity as an instance of a discrete, movable object based on a Mesh, I don't see that your current definition is sufficient, it only contains position and a draw function. You can define an entity as an Updatable object, and another class called StaticEntity no need for polymorphism. And let the Scene have two separate lists and actually be able to update the objects, again separate the renderer from the scene.
Third your Screen class should be called Renderer and have objects that can be rendered registered based on their static type. You can also have a Drawable interface.

C++ - Recommended way to allow access objects in a class to access the class they are in

I have a class Game with class EnemyManager. EnemyManager deals with spawning of enemies and the logic behind it. The problem is that EnemyManager needs access to functions and other Game objects in the game class. I can think of two ways to handle this.
Pass the address of the class object Game* using this as one of the arguments in the EnemyManager.
Declare a global pointer to a Game object and set it when initializing the Game class. Then extern it into the enemymanager.cpp.
Which is the more advisable way to do this?
Whenever I encounter situations like this I review the overall design of the related classes. If EnemyManager is a member of a Game object and needs to call things within Game, maybe those functions in Game can be factored out into a separate component. If something you are writing is beginning to feel overly-complex or like a hack it's usually time to do some factoring.
When dealing with object oriented designs, it is typically good to think about who will act how on what to find a first version of a design. After having written this version, one often finds the weaknesses and rewrite it for the second iteration.
So, in this case, the Game class manages the world (I assume) and offers different ways to manipulate it. Your EnemyManager manages one aspect of the world, enemies, but they do live inside the world.
class Enemy {
public:
Enemy(Location& location, int hitpoints);
bool Move(Direction& direction);
};
class Game {
public:
bool CreateInitialState();
bool AddEnemy(Enemy& enemy);
bool AddBullet(Location& location, Direction& direction, int speed);
void Render();
};
class EnemyManager {
public:
EnemyManager(Game& game);
void MoveEnemies();
};
In this first version, all types see each other as proper classes and manipulates things by calling the appropriate method. This offers little support for expanding on the game if you want to add new things to it.
This is where interfaces become handy and you can try to think about how the different parts will interact instead of how they should be implemented.
class Canvas {
public:
// Different graphical primitives.
};
class GameObject {
public:
virtual ~GameObject() {};
virtual void Draw(Canvas& canvas) = 0;
virtual bool Move(Direction& direction) = 0;
};
class GlobalState {
public:
virtual AddGameObject(GameObject& gameObject) = 0;
};
class Game : public Canvas, public GlobalState {
public:
bool CreateInitialState();
void Render() {
// Send itself to the Draw method in all GameObjects that have been added
}
// Other game logic
};
class Enemy : public GameObject {
// This can be specialized even more if you need to
};
class Bullet : public GameObject {
// This can also be specialized even more if you need to
};
This separates design from implementation and, as I see it, is a good way to end up with a proper first attempt.
It is hard to say without knowing the overall architecture layout, but my 2 cents:
The way you describe as a first one is called the dependency injection and is widely used all around. You should keep an eye on what methods/fields you're making public.
I assume that Game class has the methods that should not be accessible from the EnemyManager class, thus is seems like it's a good idea to create the interface which has the declaration of the methods that are used by EnemyManager and then pass the pointer to the EnemyManager instance (instead of the Game).
For example: The Game class implements IGameEnemyManager, and you're passing IGameEnemyManager using this as one of the initialization arguments.
If you are handling game objects in EnemyManager, why is it part of the class Game ? I suppose you should consider reviewing your design as there are chances of circular reference problem if you don't handle the scenarios well.
Consider segregating both the classes to ensure a single responsibility principle.
Define proper interface in yourEnemyManagerto Game object as argument and act on the functions
These are little suggestions that I can think of with limited idea about your design
You're absolutely need to use the 1st approach, but with a few changes: you should disintegrate your Game class to more components. For example you can create a SceneManager class, which is responsible for all game object's creation/management. When you're instantiating the EnemyManager - just pass a pointer to it:
// in SceneManager
EnemyManager* emgr = new EnemyManager(this);
InterfaceManager* imgr = new InterfaceManager(this);
Note that your SceneManager class should provide a complete interface
// in EnemyManager
GameObject* spawnEnemyAt(string name, EnemyClass* eclass, Vector3 position, AIBehaviour* behaviour)
{
GameObject* myEnemy = smgr->createGameObject(name, position, etc...);
//register an enemy in the enemies list, initialize it's behaviour and do any other logic
return myEnemy
}
This approach should help you not to ruin your architecture and not to be captured in the friend(class)-zone.
[Upd.] Note that my approach assumes that all objects on the scene are GameObjects, there's neither Enemy nor Player classes. Every GameObject may has a Renderer, Animator, AIBehaviour components.

Defining a type only by its inheritance from other classes

I am implementing a visual tree in SFML. SFML contains two important drawing classes: sf::Drawable and sf::Transformable. It would be nice if these were bundled up together, but they are not. Many objects inherit from both, i.e.:
class SFML_GRAPHICS_API Text : public Drawable, public Transformable
class SFML_GRAPHICS_API Sprite : public Drawable, public Transformable
class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
For my visual tree, I have a SceneNode class that inherits from Drawable and Transformable, and a draw function will call a private onDraw itself, and then its children. However, many SFML native classes, such as sf::Text, have a draw function that is private. So, I cannot create a class like
class Text: public sf::Text, public SceneNode
and then put it into the visual tree. For these native classes, I don't need them to have draw children anyway, I just want to be able to add them to the visual tree as leaf nodes. The crux of the problem is that each member of the visual tree needs to inherit from sf::Drawable and sf::Tranformable. I need to be able to define a type that inherits from both of these. If I define the dummy class
class LeafNode: public sf::Drawable, public sf::Tranformable { }
which appears to define the type I want. Then, SceneNode will contain std::vector<LeafNode*> m_children. When drawing these children, I will do a dynamic cast on each item to see if it is a SceneNode, and then call a draw function so the SceneNode draws its children.
However the following code does not compile due to type incompatibility:
LeafNode * node = new sf::Text("PLAY", font, 20);
Ideally, I want to define something like
std::vector<sf::Drawable, sf::Transformable*> m_children
Where that made-up syntax means that each element must derive from both sf::Drawable and sf::Transformable. Is this possible?
However, many SFML native classes, such as sf::Text, have a draw function that is private
That's not quite true. Since the sf::Drawable::draw function is protected, so is the draw method of sf::Text. It's one of the complex rules of C++.
So, I cannot create a class like
class Text: public sf::Text, public SceneNode
If you did you would have two sf::Drawable and sf::Transformable base classes in your hierarchy, one from sf::Text and one from SceneNode. That wouldn't be good.
When drawing these children, I will do a dynamic cast on each item to see if it is a SceneNode, and then call a draw function so the SceneNode draws its children.
I would not recommend such design. Using dynamic_cast is usually a sign your software design is not so great. (I don't want to digress too much on this topic, google about that topic.)
But let's answer your fundamental question:
Where that made-up syntax means that each element must derive from both sf::Drawable and sf::Transformable. Is this possible?
No. But you can do simpler things anyway.
Instead of having Text inheriting from both sf::Text and SceneNode, define you class as a wrapper. It can be as simple as:
class Text : public SceneNode {
sf::Text m_text;
public:
sf::Text& get() { return m_text; }
// Override SceneNode drawing method:
virtual void onDraw(RenderTarget& target) const
// Draw m_text:
target.draw(m_text);
}
};
There is two flaws with this quick wrapper, though. a) It doesn't use the transformable part of the SceneNode. b) Since the encapsulation is broken with get() there are two transformable modifiable by the user: the one from SceneNode and the one of sf::Text.
For a), the fix should be straightforward when you have fixed b). To fix b), you have to make the wrapper a little bit more complex: instead of having this ugly get(), write methods to set the properties of the underlying sf::Text that are not linked to sf::Transformable, e.g. setColor.
Without knowing anything about SMFL (which may provide better solutions) I think you can implement this vector. You only need to define your own pointer wrapper, which only accepts pointers to objects which inherits from more than one type:
template <class T1, class T2>
struct special_pointer_wrapper
{
T1* t1;
T2* t2;
template<class T>
special_pointer_wrapper(T* p)
: t1(dynamic_cast<T1*>(p))
, t2(dynamic_cast<T2*>(p))
{
if ((p1==0) || (p2==0))
throw "Error";
}
getT1 T1* () const { return t1; }
getT2 T2* () const { return t2; }
};
This class takes any pointer and ensures its pointed to type is derived from T1 and T2 (even if they seem to be totally unrelated). If its not a derived object it throws. With functions getT1() and getT2() it gives you access to pointers to both base classes.
Please note the construction may be slow due dynamic_cast but extraction of the types is O(1).

I'm attempting to practice Polymorphism and OOD principles [in C++]. Need guidance and answers to a couple questions

I'm writing a simple 2D game centered around mazes with RPG elements. It is primarily for learning purposes to practice class design, graph theory algorithms, data structure use, and using 2D graphics.
Brief Overview of the Program:
The game itself is tile based. It currently generates and draws mazes to the screen, allows for player movement, and collision detection for walls; in addition it can handle screen scrolling for larger mazes.
Anyway, right now I'm working on building an object which handles placing objects around the map. First on the list is gold coins, then things like hearts and items. I thought this would be a good time to practice inheritance and polymorphism, but I haven't had any formal training in this kind of design. Here is the header file:
#ifndef MAP_OBJECT_H
#define MAP_OBJECT_H
#include "Common.h"
#include "Utility Functions.h"
const int TILE_SIZE = 80;
class MapObject
{
public:
MapObject(unsigned int nClips, unsigned int r, unsigned int c, unsigned int cSize) :
sheet(0), clips(0), row(r), col(c), numClips(nClips), clipSize(cSize)
{
//For those of you who aren't familiar with sprite sheet usage, basically this
// handles which part of the sprite sheet your on, so it will draw the correct sprite to the screen
if(numClips > 0) clips = new SDL_Rect[numClips];
box.h = clipSize;
box.w = clipSize;
}
virtual ~MapObject() //NOt sure if this is right. All the derived classes will
// behave the same upon deletion, since the only resource
// that got allocated was for the box SDL_rect
{
if(clips) delete[] clips;
}
void initBox(int modX, int modY);
//I think each object will draw a little different, so I made it virtual
virtual void draw() = 0;
//Same with interaction--although I'm not sure how my player class is going to be able to handle this yet
virtual void interact() = 0;
SDL_Rect getBox() const;
private:
SDL_Surface* sheet;
SDL_Rect box;
SDL_Rect* clips;
unsigned int row, col;
unsigned int numClips;
unsigned int clipSize;
MapObject() {} //Made this private because I want the memory to be allocated, and
// numClips needs to be initialized for that to happen, so
//basically I'm forcing the user to use the constructor with parameters
};
class Coin : public MapObject
{
enum CoinFace //This represents all the different coin facings in the sprite
//sheet, so that is can animate. Used in the draw function.
{
FRONT,
TURN1,
TURN2,
TURN3,
USED
};
CoinFace active;
public:
virtual void draw(SDL_Surface* destination);
virtual void interact();
};
#endif //MAP_OBJECTS
My biggest question is a general one: is this a good start to my design? Are their glaring problems? Misuses of OOD principles/conventions?
Will defining the virtual destructor like that allow for all the derived classes to use it? Or do I need to define it for each derived class?
I realize this is a lot, and I appreciate any help. I'm REALLY trying to understand OOD and how to use polymorphism, so help from some pros would be incredibly useful.
Thanks again.
EDIT: Big question I have also is the problem of begin able to modify private data members in the derived classes. I hear it's bad class design if I need to do this, and I'm not sure how to write a good interface, I guess.
Part of the question relies on a matter of opinions. Nevertheless:
All I can say here is that your approach can work, and you're well on your way to have that working. Just don't forget to define the constructor of Coin.
The whole purpose of the virtual destructor is to call the appropriate destructor when we only have a pointer of a base class type. In addition, the derived destructor is performed before the base destructor is automatically called, without having to call it explicitly. In this case, a Coin pointed by a MapObject* will be destroyed correctly with delete, which performs ~Coin() and ~MapObject(), in this order.
That question can easily turn into a debate on proper interface construction, but here are a few solutions:
Define private members via the constructor, preventing them from being modified by other classes.
Make members in a base class protected instead of private. This might be the simpler solution to what you wish to do here.
Create setters for the private member types, like setActive(CoinFace). You can adapt these functions to your needs, like preventing invalid definitions for an attribute that would make the whole object inconsistent. Like the previous solution, you can make these setters protected, so that only derived classes can access them.
Make the class a friend of another class (calling it A). Instances of A can take objects of that class and access all its private members.