Restricting templated class datatypes - c++

I have the following class definitions:
// A TileBase contains a deceleration for game events that will be present in
// Static and Dynamic tiles
class TileBase
// To use tiles in your game, create a tile base for Tile to inherit from, then
// create game-specific tiles as derivitives of StaticTile or DynamicTile
template<typename aTileBase> class Tile : public aTileBase
Classes StaticTile and DynamicTile are derived from Tile. The goal is to have methods declared in a TileBase present in all derived classes of Tile via a dynamic cast.
I would like to restrict Tile's template definition to only accept datatypes derived from TileBase. Is there any way to accomplish this without using a dynamic cast and assertion at runtime?

That's easy to do using std::is_base_of<>
template<typename aTileBase>
class Tile : public aTileBase {
static_assert(std::is_base_of<TileBase, aTileBase>::value, "");
[...]
};

Related

derived class of a base class functioning as an abstract class

I have defined a super class element. There are some derived class of element say triangle , quad and cube. Some of the element objects are boundary element. If the element is boundary element, then I have to define additional data members and functions. I could have easily derive a boundary_element class if the element class is not base class.(What I meant is, if triangle , quad and cube are separate classes I can define separate derived classes like boundary_triangle , boundary_quad , andboundary_cube).
So my problem is I have to define a subclass boundary_element which has to be the base (or even abstract) class for defining derived classes boundary_quad , boundary_triangle and boundary_cube.
Is this somehow possible in C++? could anyone suggest any architecture which serves the purpose?
Another way I can solve my problem according to my logic is, define a class like below:
class boundary_element
{
element* m_boundary_elem;
//data members needed for quad,triangle and cube
public:
boundary (element*);
//functions for modifying data's of triangle,cube,quad.
}
The element pointer is defined as member variable of another class. How do I restructure this class effectively using inheritance. ( i.e Function it as an abstract class, for deriving boundary_triangle , boundary_quad, and boundary_cube class )
I don't know my question is weird but as a beginner I'm really confused how to use inheritance properly. Sorry if my heading is misleading.
C++ has multiple inheritance, so you can derive from Element and Boundary at the same time and avoid code duplication.
Something like this:
class Element {
};
class Boundary {
};
class Triangle : public Element {
};
class BoundaryTriangle : public Triangle, public Boundary {
};
. . .
Is this somehow possible in C++?
Of course it is.
could anyone suggest any architecture which serves the purpose?
Something along these lines:
Have an abstract base class and interface
class AbstractShape {
boundary getBoundary() const = 0;
void draw(OutputScreen& screen) const = 0;
};
Have implementations for particular shapes like
Triangle : public AbstractShape {
// Implement the triangle specifics
};
Rectangle : public AbstractShape {
// Implement the rectangle specifics
};
Circle : public AbstractShape {
// Implement the circle specifics
};

How to make convince compiler object will be an of a derived class?

I'm having a problem with inheritance and I don't know if it's a design flaw or not, and how to approach it if it is. I have a case with four classes: two bases and two derived. I'll use an alternative example:
class Player { // base class for a player in general
...
}
class Game { // base class for a game in general
...
Player * players; // dynamically allocated at run-time
...
}
class BaseballPlayer : public Player {
...
void hitHomeRun();
...
}
class BaseballGame : public Game {
...
...
players[i].hitHomeRun(); // this causes compiler error
}
The error I get is because the method isn't defined in the base class, but the array is of the type base class. In the BaseballGame class, only BaseballPlayers are loaded into the array, but I can't convince the compiler of that. Is this a matter of casting? How do I guarantee the compiler that players will be full of the correct objects? Can I override the Player * players member itself with a BaseballPlayer * team in the derived class?
This is pretty much standard.
template <typename P>
class Game {
std::vector<P> players;
...
class Player ...
class BaseballPlayer : public Player ...
class BaseballGame : public Game<BaseballPlayer> ...
Yes this seems to be a design flaw. Your players are only going to be only BaseBallPlayers or CricketPlayers. While Player will be only contain the common info about player, ie. age, name, DOB etc. while its specialization will contains its info about his records.
Two suggestions.
1> class Game: Every game has players. change Player * players; to Player * **players; . So Game will contain dynamically allocated array of pointer to players.
2> class BaseBallPlayer and class player. Override the BaseBallPlayer::hitHomeRun and declare same as virtual void Player::hitHomeRun.
and change call to players[i].hitHomeRun(); as dynamic_cast<BaballPlayer*>(players[i])->hitHomeRun();. virtual override will call the BaseBallPlayer::hitHomeRun. dynamic_cast is only applicable for virtual inheritance or base class should contain at least one virtual method.

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).

Composition pattern

How should one approach composition instead of inheritance? Consider the following class:
class GameObject {...};
class Sprite {
public:
void changeImage(...);
};
class VisibleGameObject: public Sprite, public GameObject {};
class VisibleGameObject : public GameObject {
protected:
Sprite m_sprite;
};
The first VisibleGameObject class uses inheritance. Multiple inheritance. Does not looks good. Second one is what i would like to use, but it won't allow me to access Sprite's API like this:
VisibleGameObject man;
man.changeImage();
How can that be accomplished without inheritance (or code duplication)?
EDIT:
I do know I can just use inheritance or make m_sprite a public member and I can't access the Sprite class because it's private. That's the point, the question is about the best way to change a VisibleGameObject's Sprite, following the rules of data encapsulation.
I think you are still one step behing "composition over inheritance" mindset. The base class should know what to composite. To change image, you should change sprite instance, you shouldn't provide interface of composed instances. For example:
class GameObject {
public:
// you can choose public access or getters and setters, it's your choice
Sprite sprite;
PhysicalBody body;
};
object = GameObject();
object.sprite = graphicalSystem.getSpriteFromImage("image.png");
// or if you prefer setters and getters
object.setSprite(sprite);
More generally GameObject should contain instances (or pointers to instances, depends on your implementation) of base class Component. It makes sense to use inheritance in this case, because this way they can be in one storage like std::map. For example:
class Component {
// ...
};
class Sprite : public Component {
//...
};
class PhysicalBody : public Component {
//...
};
class GameObject {
protected:
std::map<std::string, Component*> components;
//...
public:
Component* getComponent(const std::string& name) const;
void setComponent(const std::string& name, Component* component);
//...
};
For component creation and rendering in main loop use Systems. For example GraphicalSystem knows all instances of Sprite it has created and while rendering it renders only sprites attached to some GameObject instance. Detached component can be garbage collected. Information about position and size might be part of the GameObject or it might be a component "physical".
The best way to understand it is to write your own prototype or to check existing implementations (Artemis, Unity 3D and many others). For more information see Cowboy programming: Evolve Your Hierarchy or try to find Entity/component system.
First of all, the alternative for composition is private inheritance (and not public one) since both model a has-a relationship.
The important question is how can we expose Sprite public members (e.g. changeImage) to VisibleGameObject clients? I present the 4 methods that I know:
(Private) inheritance
I understand that you want to avoid (multiple) inheritance, but for the sake of completeness, I present one suggestion based on private inheritance:
class VisibleGameObject: private Sprite, public GameObject {
...
};
In this case VisibleGameObject privately derives from Sprite. Then users of former cannot access any member of the latter (as if it it were a private member). In particular, Sprite's public and protected members are hidden to VisibleGameObject clients.
Had the inheritance been public, then all Sprite's public and protected members would be exposed by VisibleGameObject to its clients. With private inheritance we have a finer control of which methods should be exposed through using declarations. For instance, this exposes Sprite::changeImage:
class VisibleGameObject1: private Sprite, public GameObject {
public:
using Sprite::changeImage;
...
};
Forwarding methods
We can give to VisibleGameObject public methods that forward the call to m_sprite as show below.
class VisibleGameObject2: public GameObject {
public:
void changeImage() {
m_sprite.changeImage();
}
private:
Sprite m_sprite;
...
};
I believe this is the best design, especially as far as encapsulation is concerned. However, it might require a lot of typing in respect to other alternatives.
Structure dereference operator
Even plain old C provides types that exposes another type's interface as if it was its own: pointers.
Indeed, suppose that p is of type Sprite*. Then by using the structure dereference operator -> we can access members of Sprite (pointed by p) as shown below.
p->changeImage();
C++ allows us to endow classes with customised struct dereference operators (a feature well used by smart pointers). Our example becomes:
class VisibleGameObject3 : public GameObject {
public:
Sprite* operator ->() {
return &m_sprite;
}
private:
Sprite m_sprite;
...
};
and
VisibleGameObject v;
v->changeImage();
Although convenient, this method has many flaws:
As for public inheritance, this approach doesn't give a fine control over which Sprite public members should be exposed.
It works only for one member (that is, you cannot use the same trick to expose two members interfaces).
It messes up with the interface. Indeed, consider for instance that VisualGameObject has a method doSomething(). Then, to call this method on an object v one should do v.doSomething() whereas to call changeImage() one should uses v->changeImage(). This is confusing.
It makes VisibleGameInterface to look like a smart pointer. This is semantically wrong!
C++11 Wrapper Pattern
Finally, there's Sutter's C++11 Wrapper Pattern (watch his presentation, specifically the second slide of page 9):
class VisibleGameObject4 : public GameObject {
private:
Sprite m_sprite;
public:
template <typename F>
auto operator()(F f) -> decltype(f(m_sprite)) {
return f(m_sprite);
}
};
Clients use it this way:
VisibleGameObject4 v4;
v4( [](Sprite& s) { return s.changeImage(); } );
As we can see, compared to the forwarding methods approach this transfer the burden of typing from the class writter to the class clients.
It looks like you are trying to directly access Sprite's function without referencing it first. Try this:
man.m_sprite.changeImage() ;
Note that m_sprite and changeImage() should be public for you to do this. Otherwise use a public accessor function to manipulate private class members.

Designing classes for inheritance

Suppose I have a class Entity.
And then I have n number of classes which is derived from Entity
eg :
class Snake : public Entity{...};
class Mouse : public Entity{...};
Now I have a class player that is an entity.
Can I create a class player that inherits from any type of entity?
eg :
class Player : public Entity -->(but instead of entity be any type of entity)
Can this be done?
Is this achieved by using templates?
I've read that the templates can be explicitly specified in a cpp file i.e
template class Entity<Snake>;
I am trying to achieve the following
In my player class I have a moveCamera function inside move Now only when a player moves, the camera moves .. If an AI Snake moves the camera should not move.
this is my render function in the entity class which is virtual
void Entity::Render(float interpolation)
{
if(currentAnimation != 0){
float x = this->currLocation.x - (this->currentVelocity.x * (1.0f - interpolation)) - camera->getLocation(L_FACTOR_CURRENT).x;
float y = this->currLocation.y - (this->currentVelocity.y * (1.0f - interpolation)) - camera->getLocation(L_FACTOR_CURRENT).y;
currentAnimation->Render(x,y);
}
}
This is my gameUpdate function and basically moves an entity to its respective world co-ordinates
void Entity::GameUpdate(float gameUpdateDelta)
{
this->Move();
}
Therefore for my player's move function I will call the camera's move function and then call the base class's move function... Now is it possible to call the extended class of the base's class move function..
My Move function is virtual and therefore a snake and mouse can move differently..
You may want to write a template class Player that inherit from Template parameter.
template< typename Derived >
class Player:
public Derived, // we believe that Derived inherits Entity
public IPlayer // makes sense if Player is not a Entity only interface
{
... some declaration here ...
void update(); // some virtual method from Entity interaface
void player_action(); // some virtual method from IPlayer interaface
}
When create a concrete type of player, you may place it one your scene.
IPlayer* player1 = new Player<Snake>("Player1");
Entity* playerEntity = dynamic_cast< Entity* >( player1 );
if( playerEntity ) // test if object can be placed on scene
{
scene->add( playerEntity );
}
You may also need to know how to write partial template specialization of class methods.
Also you may find boost enable_if as a powerful toy.
It would be more helpful for people to help if you can publish the interface (just the class definition) of your current design. It looks like you need to make player own snake and mouse. Use observers if you want some action to be associated with other actions.