I'm wondering what is the recommended way to avoid the issue below.
I have a class rigidBody3D that has a pointer to another rigidBody structure, and a class box3D that inherits rigidBody3D.
class rigidBody3D {
public:
void setPosition(float x, float y, float z);
rigidBody* rb;
};
class box3D : public rigidBody3D {
public:
box3D(float w float h, float l);
..other box functions..
};
I then have 2D classes that use these 3D classes.
class rigidBody2D {
public:
rigidBody2D();
void setPosition(float x, float y);
rigidBody3D body;
};
class box2D : public rigidBody2D {
public:
box2D(float w, float h);
box3D box;
};
For example rigidBody2D's setPosition calls the 3D setPosition of its rigidBody3D.
void rigidBody2D::setPosition(float x, float y)
{
body.setPosition(x,y,0);
}
THE ISSUE:
As is, creating a box2D object creates two rigidBody pointers. One because box2D inherits rigidBody2D which has a rigidBody3D. The other because box2D has a box3D object that inherits rigidBody3D.
I only want one rigidBody pointer. I also want to be able to call the 2D setPosition for 2D classes like box2D, but also call their 3D specific functions, like box2D calling box3D.
SOLUTION:
I used virtual inheritance to solve the problem, and also inherited the 3D classes instead of having objects of them.
class rigidBody3D {
public:
void setPosition(float x, float y, float z);
rigidBody* rb;
};
class box3D : public virtual rigidBody3D {
public:
box3D(float w float h, float l);
..other box functions..
};
class rigidBody2D : private virtual rigidBody3D {
public:
rigidBody2D();
void setPosition(float x, float y);
};
class box2D : public rigidBody2D, private box3D {
public:
box2D(float w, float h);
};
void rigidBody2D::setPosition(float x, float y)
{
rigidBody3D::setPosition(x,y,0);
}
Your comment:
I want (...) 2D objects, which are 3D objects that are drawn in 2D and have their z
components set to 0
strongly suggest that a rigidBody2D is a rigidBody3D, and that a box2D is a box3D. Hence it would seem natural to prefer inheritance over compostion:
Alternative 1: simple inheritance
Here we'll consider that the root of all these 2D and 3D objects is the rigidBody2D.
One question remains: is a box2D more a kind of box3D or more a rididBody2D ?
class rigidBody2D : public rigidBody3D {
public:
rigidBody2D();
void setPosition(float x, float y);
// no body anymore: it's inherited from rigidBody3D
};
class box2D : public box3D { // is it more like a box3d or more like a rigiBbody2D ? You decide !
public:
box2D(float w, float h);
// no box anymore: it's inherited from box3D
};
box2D::box2D (float w, float h) : box3D (w, h, 0) { /*...*/ } // how to create a box2D as a special case of box3D
void rigidBody2D::setPosition(float x, float y) // call the setpos of the parent.
{
rigidBody3D::setPosition(x, y, 0); // call parent's setpos
}
All therse objects inherit from rigidBody3D and have then a pointer to a rigidBody.
A further question is in fact to know whether a rigidBody3D should not himself inherit from a rigidBody, or if there are strong arguments against (for ex: if the lifespan of the two are different).
Alternative 2: multiple inheritance
Here it's about the design of box2D. Is it more a box3D, having the same kind of member functions but than a box3D, but taking into account that third dimension is 0 ? Or is it more a rigidBody2D, because it should have and use all the member functions provided by this object ?
If you can easily decide, go back to alternative 1.
If you can't decide, because it's a little bit both, then you could consider multiple inheritance:
class box2D : public box3D, public rigidBody2D {
public:
box2D(float w, float h);
// no box anymore: it's inherited from box3D
};
THen you would inherit member (function and data of both). Hower multiple inheritance ain't easy. You'd have here 2 rigidBody pointers: those who are inherited from the box, and those who are inherited from the body.
This issue could be solved in your case by making inheritance of rigidBody3D virtual:
class rigidBody2D : public virtual rigidBody3D { ... };
class box3D : public virtual rigidBody3D { ... };
in this case, if an object inherits several time rigidBody3D, only one of such subobject is created.
it seems to me that 2d and 3d objects are related only by the fact that they are implemented in terms of a rigidbody*. The semantics of setPosition are different for the two concepts.
Another way to say this is that a 2d body is not a kind-of 3d body, it's a different concept so it seems that there should be no inheritance relationship between them.
so I would start by thinking along these lines:
struct rigid_body_3d_concept {
virtual ~rigid_body_3d_concept();
void set_position(double x, double y, double z) {
_impl->really_set_the_position(x, y, z);
}
private:
rigidbody* _impl;
};
struct rigid_body_2d_concept {
virtual ~rigid_body_2d_concept();
void set_position(double x, double y) {
_impl->really_set_the_position(x, y, 0);
}
private:
rigidbody* _impl;
};
struct box3d
: public rigid_body_3d_concept
{
box3d(double w, double h, double l);
};
struct box2d
: public rigid_body_2d_concept
{
box2d(double w, double h);
};
Related
i've a problem drawing basic shape with fltk.
I've made 2 classes'Rectangle' and 'Circle' that show normally. Then i've created a third class that inherit from 'Rectangle' and 'Circle' called 'RectangleAndCircle' :
//declaration in BasicShape.h
class Rectangle: public virtual BasicShape, public virtual Sketchable{
int w,h;
public:
Rectangle(Point center, int width=50, int height=50, Fl_Color fillColor=FL_WHITE, Fl_Color frameColor=FL_BLACK);
void setPoint(Point new_p){center=new_p;}
virtual void draw() const override;
};
class Circle:public virtual BasicShape, public virtual Sketchable{
int r;
public:
Circle(Point center, int rayon=50, Fl_Color fillColor=FL_WHITE, Fl_Color frameColor=FL_BLACK);
virtual void draw() const override;
};
class RectangleAndCircle: public virtual Rectangle, public virtual Circle{
public:
RectangleAndCircle(Point center,int w, int h, int r,
Fl_Color CircFillColor, Fl_Color CircFrameColor,
Fl_Color RectFillColor, Fl_Color RectFrameColor);
void draw() const override;
When i try to draw a 'RectangleAndCircle' instance, the rectangle and the circle share the same color even if i the rectangle color is set.
Here is the code for the constructor of 'RectangleAndCircle' and the drawing of the shapes :
RectangleAndCircle::RectangleAndCircle(Point center, int w, int h, int r, Fl_Color CircFillColor,
Fl_Color CircFrameColor, Fl_Color RectFillColor, Fl_Color RectFrameColor)
:Rectangle(center,w,h,RectFillColor,RectFrameColor)
, Circle(center,r,CircFillColor,CircFrameColor){}
void Rectangle::draw() const {
fl_begin_polygon();
fl_draw_box(FL_FLAT_BOX, center.x+w/2, center.y+h/2, w, h, fillColor);
fl_draw_box(FL_BORDER_FRAME, center.x+w/2, center.y+h/2, w, h, frameColor);
fl_end_polygon();
}
void Circle::draw() const {
fl_color(fillColor);
fl_begin_polygon();
fl_circle(center.x, center.y, r);
fl_end_polygon();
}
void RectangleAndCircle::draw() const {
Rectangle::draw();
Circle::draw();
}
I create a instance of 'RectangleAndCircle' in my MainWindow class, and i draw it.
RectangleAndCircle r{Point{50,50},50,50,12,FL_RED,FL_BLACK, FL_WHITE, FL_BLACK};
...
r.draw()
Am i doing something wrong ?
You're using virtual inheritance. This means there will be only one instance of BasicShape in RectangleAndCircle. This BasicShape will have its fillColor set by both the Rectangle and Circle constructors, whichever being called last overwriting the value.
My advice would be to not inherit here, and instead have two fields of type Circle and Rectangle in RectangleAndCricle and then call draw on those separately in draw. Inherit to be reused, not reuse (you presumably wouldn't want to pass a RectangleAndCricle as a Circle or Rectangle)
I am trying to create an "alien invaders" game by myself. In order to create enemies and player, I created a class called "entity" and made subclasses of it. Like Player, shootingEnemy, IdleEnemy. When coding I realised gathering them in a vector<Entity> would make my collision detection function much easier.
After searching on the internet I learned this is called "object slicing" and makes copies of of ony le base part of objects.
So the final version became this.
int main()
{
int BoardWidth = 50;
int BoardLength = 30;
vector<Bullet> bullets;
vector<Entity*> SpaceShips;
setup(SpaceShips, BoardWidth, BoardLength);
double ElapsedTime = 0;
int PreviousRoundSec = 0;
int PreviousRoundQSec = 0;
DrawGame(BoardWidth, BoardLength, SpaceShips, bullets);
int IsGameOver = 0;
auto start = chrono::steady_clock::now();
while(!IsGameOver)
{
// Updates EverySecond
if ((int)(ElapsedTime / 1000) > PreviousRoundSec)
{
PreviousRoundSec = (int)(ElapsedTime / 1000);
}
// Updates every quarter of a second
if ((int)(ElapsedTime / 250) > PreviousRoundQSec)
{
PreviousRoundQSec = (int)(ElapsedTime / 250);
}
// To keep time
auto end = chrono::steady_clock::now();
ElapsedTime = chrono::duration_cast<chrono::milliseconds>(end - start).count();
}
if (IsGameOver == 1)
{
// conjualations
}
else if (IsGameOver == 2)
{
// GameOver
}
return 0;
}
But when I try use some subclass specific functions I get an compiler error saying 'CLASS "Entity" does not have any member called "shoot"'.
I am trying to practice classes and polymorphism so I do not even know this has a solution because compiler doesn't have any way of knowing which element of this vector belongs to which subclass.
Also this is my classes header page in case needed.
class Entity
{
public:
int x;
int y;
int width;
int length;
int hp;
bool shooting;
public:
Entity(int x, int y, int width, int length, int hp, bool shooting): x(x), y(y), width(width), length(length), hp(hp), shooting(shooting) {}
};
class Bullet : public Entity
{
private:
char dir;
int ID;
public:
Bullet(int x, int y, char GivenDir, int GivenID) : Entity(x, y, 1, 1, 1, false) { dir = GivenDir; ID = GivenID; }
void Move();
void IfHit(vector<Entity>& SpaceShips);
void IfOut();
};
class Player : public Entity
{
private:
char action = 'a';
public:
Player(int x, int y, int hp) : Entity(x, y, 3, 2, hp, true) {}
void GetAction();
void Move();
void Shoot(vector<Bullet>& bullets);
bool IfHit(vector<Entity>& SpaceShips, vector<Bullet>& bullets);
};
class IdleEnemy : public Entity
{
public:
IdleEnemy(int x, int y, int hp) : Entity(x, y, 3, 2, hp, false){}
bool IfHit(Player* player, vector<Bullet> &bullets);
void Move(char HordDir);
};
class ShootingEnemy : public Entity
{
public:
ShootingEnemy(int x, int y, int hp) : Entity(x, y, 3, 2, hp, true) {}
void Shoot(vector<Bullet> &bullets);
bool IfHit(Player* player, vector<Bullet> &bullets);
void Move(char HordDir);
};
You need to check runtime polymorphism in C++. Let's check it out how can you do that. First of all, you need to change your Entity class interface. You need to add virtual or pure virtual functions. I have added pure virtual function;
class Entity
{
public:
int x;
int y;
int width;
int length;
int hp;
bool shooting;
public:
Entity(int x, int y, int width, int length, int hp, bool shooting) : x(x), y(y), width(width), length(length), hp(hp), shooting(shooting) {}
void virtual Move() = 0; // pure virtual function
void virtual IfHit() = 0; // pure virtual function
};
Virtual functions are overridable functions. Also, they have implementations but when we are talking about pure virtual functions they only provide an interface for the class. You need to override that function in your derived class. When you are implementing your derived class you need to do like this,
class Bullet : public Entity
{
private:
char dir;
int ID;
public:
Bullet(int x, int y, char GivenDir, int GivenID) : Entity(x, y, 1, 1, 1, false) { dir = GivenDir; ID = GivenID; }
void Move()override;
void IfHit();
void IfOut();
};
class Player : public Entity
{
private:
char action = 'a';
public:
Player(int x, int y, int hp) : Entity(x, y, 3, 2, hp, true) {}
void GetAction();
void Move();
void Shoot(vector<Bullet>& bullets);
void IfHit()override {//code};
};
class IdleEnemy : public Entity
{
public:
IdleEnemy(int x, int y, int hp) : Entity(x, y, 3, 2, hp, false) {}
void IfHit()override;
void Move()override;
};
class ShootingEnemy : public Entity
{
public:
ShootingEnemy(int x, int y, int hp) : Entity(x, y, 3, 2, hp, true) {}
void Shoot(vector<Bullet>& bullets);
void IfHit()override;
void Move()override;
};
These functions can be implemented either inline or in a source file. Also, there is an important point of these functions is the return value, function signature, and names' must be identical unless you do not use covariant return type.
As seen in the derived classes some of the functions are not common. I know your question how can I use that :) As mentioned ttemple in the comments you need to use dynamic_cast operator.
int main()
{
Entity* ptr = new ShootingEnemy{ 1,2,4 };
ptr->Move();
ptr->IfHit();
if (auto SE = dynamic_cast<ShootingEnemy*>(ptr))
SE->Shoot(...);
}
dynamic_cast operator is a runtime conversion operator. It converts the type of base class pointer to the derived class. It is called downcasting. Also, it checks that base class pointer points to the target derived class. If the dynamic_cast operation is completed with fail then it returns null and if statement becomes fail. Via that way, you can use runtime polymorphism and class member functions.
By the way, avoid object slicing as possible. You are losing derived class properties.
To better understanding please refer classes dynamic_cast
The compiler tells you the truth. You have a pointer to an Entity, which obviously does not have Shoot method in its interface, so how could you possibly call it without any cast?
The idea behind dynamic polymorphism which you are trying to implement here is about having a common interface (your base class, Entity), with specific implementation in each sub-class. So, publicly available methods signatures are going to be common for all subclasses, but not the implementations.
From the design perspective, cleanest approach would be to rename Entity to ShootableEntity and declare a pure virtual Shoot method in there. Then all sub-classes shall provide some implementation.
If not all of them implement Shoot, yet you are trying to use them generically in such manner, maybe you should reconsider the approach, eg. create two containers - for shootable entities and for non-shootable entities. Then, when iterating over shootable-entities (instances of classes which actually subclass ShootableEntity, which contain Shoot declaration), you could call Shoot on base class' pointer without any problems.
Your Entity does not represent any common interface, however. So, if you are trying to make use of polymorphism (so, you have a pointer to the base class, yet behind that pointer there's some concrete instance), such class won't do you any good.
In fact, the doc itself has a great explanation: http://www.cplusplus.com/doc/tutorial/polymorphism/
I'm currently learning about C++ Inheritance, so if this question is a dumb one, I apologize in advance.
Implementing this scenario:
A super class has a color attribute, which can be any color (let's assume color is represented by an integer).
Let's assume I have an initialization of this super class, with the color red.
I am also going to initialize different objects of a sub-class which also share the color red.
My question is, is there any way that I can initialize this attribute color to red (or any color for that matter) and it would be automatically inherited by objects of it's sub-class, instead of setting the attribute to red every-time I initialize one of these objects?
Again apologies if I'm missing a basic concept here, but I can't seem to find anything online on this.
Pseudo-Code per request:
Super-class code:
class Shape {
int color;
Shape::Shape(int c) : color(c) { } //constructor
}
Sub-Class code:
class Square {
int length, width;
Square::Square(int l, int w, int c)
: length(l),
width(w),
color(c)
{ }
}
class Circle {
int radius;
Square::Square(int r, int c)
: radius(r),
color(c)
{ }
}
What I'm trying to say is that both square and circle need to have the same color, is there anyway (maybe from the super class? ) to declare this color (ex. red), and both shapes would have this color set the same?
You could accomplish what you want with a static default_color that gets used when no color is explicitly specified, and gets set whenever a color is specified.
struct Shape {
static int default_color;
int color;
Shape(int c) : color(c)
{
default_color = c;
}
Shape() : color(default_color) {}
};
Shape::default_color = BLACK;
struct Square : public Shape {
int length, width;
Square(int l, int w, int c)
: Shape(c),
length(l),
width(w),
{ }
Square(int l, int w)
: length(l),
width(w)
{ }
}
struct Circle : public Shape {
int radius;
Circle(int r, int c)
: Shape(c),
radius(r)
{ }
Circle(int r)
: radius(r)
{ }
}
int main()
{
Square sq(2, 3, RED);
Circle cir(10); // Automatically red, since that's
the last color explicitly specified
}
I would say this is a poor design though. Global state like this makes it very easy to make mistakes. You now have to think about the state of the entire program whenever you create a shape. It would be better to simply create the Circle as Circle cir(10, sq.color);. That makes it explicit what color your Circle is, and reduces cognitive load on the programmer.
Prior to C++11, the primary way to do this would be as follows:
class baseClass
{
int color;
baseClass() { color = RED; }
};
class subClass : public baseClass
{
subclass() { }
};
With C++11 and later, you can assign the default value in the class declaration:
class baseClass
{
int color = RED;
baseClass() { }
};
This would be inherited.
EDIT: As mentioned below, the default baseClass constructor is automatically called in this case.
There's a difference between a class and an instance of a class. A class is something like a structure, according to which further instances will be created. A class is something like a description, an instruction how to build objects. Inheritance is related to classes, not to objects. As for fields, the inherited class has all the same fields from the parent class plus some new fields you may add.
A simple example for you:
class MyBase {
public:
int color;
};
class MyChild : public MyBase {
public:
double length;
}
int main() {
MyBase myBaseObj;
myBaseObj.color = 1;
MyChild myChildObj;
myChildObj.color = 2;
myChildObj.length = 3.14;
return 0;
}
is there anyway (maybe from the super class? ) to declare this color (ex. red), and both shapes would have this color set the same?
In your posted example, yes. A super-class constructor can set its variables to whatever it wants to, for example:
Shape::Shape(int c) : color(7) { } // 7 == RED
If Shape had that constructor defined, then instances of every subclass would represent red shapes.
This sample program prints 7, overriding the user's chosen color:
#include <iostream>
class Shape {
public:
int color;
Shape(int c) : color(7) { } //constructor
};
class Square : public Shape {
public:
int length, width;
Square(int l, int w, int c)
: Shape(c),
length(l),
width(w)
{ }
};
class Circle : public Shape {
public:
int radius;
Circle(int r, int c)
: Shape(c),
radius(r)
{ }
};
int main() {
Square q(4,8,0);
std::cout << q.color << "\n";
}
I am currently developing a game in C++. Now I am a beginner in C++ and am just trying to get used to the concept of multiple inheritance. My game has a player class. That player class inherits from Positionable(gives the player x and y coords) and Moveable(allows the player to move around). The problem is that Moveable has to know the player coords to move him around adequately. Here's basic pseudo(ish) code of what I am trying to accomplish:
class Movable
{
private:
Positionable *positionable;
public:
Movable(Positionable *positionable)
: positionable(positionable)
{ }
void Translate(float x, float y)
{
positionable->setX(positionable->getX() + x);
positionable->setY(positionable->getY() + y);
}
}
class Positionable
{
private:
float x, y;
public:
Positionable(float x, float y)
: x(x),
y(y)
float getX() { return this->x; }
float getY() { return this->y; }
float setX(float val) { this->x = val; }
float setY(float val) { this->y = val; }
}
class Player : public Positionable, public Movable
{
Player(float x, float y)
: Positionable(x, y)
: Movable((Positionable) this)
{ }
}
...
Player player;
player.Translate(50, 50)
My question is is there a better way to pass Positionable to the constuctor of Movable, because if Moveable depended on 3 classes I would have to write something like Movable((FirstClass) this, (SecondClass) this, (ThirdClass) this). This looks bad. Is there some way I can solve this problem better?
As #BandiKishore suggested in the comments, a better way is to inherit Movable from Positionable (and inherit Player from Movable only). Movable needs access to coordinates to do its moving work, and the name Movable suggests that it should move itself (this), not some other object (in which case it would be Mover or MovingHelper or smth. like that), so inheritance is more logical than delegation.
Player would have to invoke only one base constructor:
class Movable : public Positionable
{
public:
Movable(float x, float y) : Positionable(x, y)
{ }
}
class Player : public Movable
{
Player(float x, float y) : Movable(x, y)
{ }
}
I would turn your IPositionable class into a struct if you are only using it to hold/access X and Y values.
If you haven't used structs before, here is a brief overview: http://www.cplusplus.com/doc/tutorial/structures/
Now as far as your IMoveable class, I would put an IPositionable member in the class as you did but intialize it in your IMoveable contstructor. Here is a really rough example of what I mean:
class IMovable
{
private:
IPositionable *positionable;
public:
IMovable(int x, int y)
{
positionable->setX(x);
positionable->setY(y);
}
void Translate(float x, float y)
{
positionable->setX(positionable->getX() + x);
positionable->setY(positionable->getY() + y);
}
}
then you'll have:
class Player
{
private IMoveable moveable;
Player(float x, float y)
: moveable(x, y)
{ }
}
...
Player player(100, 100);
player.Translate(50, 50);
This is merely building from your code example. I did not run this example locally.
Basically, you do not need to use multiple inheritance to accomplish this task. I would suggest not even using inheritance for this task as it is not needed and you should try not to use inheritance if you are not required to! It is something to be very cautious about.
I understand this isn't the best title but I'm not sure how to explain this problem that I'm having without examples.
I have a base class (called vector3)
class vector3 {
protected:
double x,y,z;
public:
vector3(): x(0),y(0),z(0) {}
vector3(double xin, double yin, double zin): x(xin),y(yin),z(zin) {}
~vector3() {}
//...other stuff
};
Then I have another class, derived from vector3, called vector4:
class vector4 : public vector3 {
protected:
double ct;
public:
vector4(): vector3(0,0,0), ct=0 {}
vector4(double ctin): ct(ctin) {}
vector4(double ctin, double xin, double yin, double zin):
vector3(xin, yin, zin), ct(ctin) {}
vector4(double ctin, vector3 v):
vector3(v.getx(), v.gety(), v.getz()), ct(ctin) {}
~vector4() {}
//...more other stuff
};
And that's all fine, but now I've got a class called particle defined like this:
class particle : public vector4 {
protected:
//vector4 r;
double mass;
//vector3 beta;
public:
particle(): vector4(0,0,0,0), mass=0, vector3(0,0,0) {}
particle(vector4 rin, double massin, vector3 betain):
vector4(rin.getx(),rin.gety(),rin.getz(),rin.getct()),
mass=0,
vector3(betain.getx(),betain.gety(),betain.getz()) {}
~particle() {}
//...Further stuff
};
So now the question is:
How do I return the x value, y value and z value of the particle's position, and the x value, y value and z value of the particle's beta vector inside a function in the particle class?
With vector 4 I'd just do:
double getx() const {
return x;
}
double gety() const {
return y;
}
etc, but what would I use in the particle's class?
Position and beta vector are attributes of a particle, so you should be using aggregation instead of inheritance:
class particle {
protected:
vector4 r;
double mass;
vector3 beta;
// ...
You should only use inheritance where there is an is-a relationship between the subclass and superclass.
In your case, particle is a vector4, so you can define your getters public in vector4, and directly call particle.getX()
However, this does not seem to be a good idea, in my opinion, particle should contain a vector since it is not a specialisation of the vector4 class.
so let's say particle has a vector called _vector
you can define a method like this :
double getX(void) const
{
return (_vector.getX());
}
Same goes for getY