C++ multiple inheritance problem using FLTK - c++

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)

Related

Why can't I declare a data member from another class private within my class definition

I am getting a compiler error saying that the data member Point p is private within the context, when I declare Point p as private within class circle. The code and compiler error are below.
#include<iostream>
#include<vector>
class Point
{
public:
Point(double a, double b)
{
x = a;
y = b;
}
virtual ~Point(){}
private:
double x;
double y;
};
The code for the class shape and circle are as follows:
class shapes {
public:
virtual Point centre() const = 0;
virtual void draw() const = 0;
virtual void rotate(int angle) const = 0;
virtual ~shapes(){}
};
class circle: public shapes {
public:
Point centre() const override { return p; }
void draw() const override { }
void rotate(int angle) const override {}
virtual ~circle() {}
circle(Point x, int r):p{x},radius{r}{}
private:
Point p;
int radius; };
Edit: Smiley face class inherits from circle class with code below:
class smiley: public circle
{ //smiley face is a circle + eyes and mouth
public:
smiley(Point p, int r):circle{p,r},mouth{nullptr}{}
Point centre() const override { return p;}
void draw() const override
{
//draw circle
circle::draw();
for(auto e:eyes)
{
e->draw();
}
mouth->draw();
}
void rotate(int angle) const {}
virtual ~smiley()
{
delete mouth;
for (auto eye : eyes) //why not delete [] eyes
{
delete eye;
}
}
private:
std::vector<shapes*> eyes; //smiley face has eyes
shapes* mouth; //smiley face has a mouth
};
If I make the data member p public in the class circle, everything works. The compiler error is listed below:
Why can I not define the Point object p, in the circle class private?
Edit: I have added the compiler error message and added the missing code asked for in the comments below. Would you be able to re-open the question?
Private class members can only be accessed within the class or by friends, so, if you would like it to be accessed outside the class by a non-friend, you would need to use a setter/getter.

How to check for collisions with SFML (While using a Base class Entity)

class Entity
{
private:
//Functions
void initiVariables();
protected:
//Variables
float velocity;
sf::Sprite sprite;
sf::Texture* texture;
MovementComponent* movementComponent;
AnimationComponent* animationComponent;
HitboxComponent* hitboxComponent;
//Component Functions
void setTexture(sf::Texture& texture);
void **strong text**MovementComponent(float maxVelocity, float acceleration, float deacceleration);
void AnimationComponent(sf::Sprite& sprite, sf::Texture& texture);
void HitboxComponent(sf::Sprite& sprite, sf::Color wireColor, float wireThickness);
public:
//Constructor & Deconstructor
Entity();
virtual~Entity();
//Accessor
const sf::FloatRect& getGlobalBounds() const;
//when I check for Collsion sprite.getGlobalBounds().intersect(sprite.getGlobalBounds())
//it remains true for the entire time what am doing wrong?
//Funtions
void setPosition(const float x, const float y);
virtual void move(const float x, const float y, const float& dt);
virtual void update(const float& dt);
virtual void render(sf::RenderTarget* target);
};
You can do simple inheritance from the Entity class. I don't know why your program crashes when returning sf::FloatRect objects. This should also be the correct solution to this problem.
#include <SFML/Graphics.hpp>
#include <iostream>
class Entity : public sf::RectangleShape {
public:
bool isColliding(Entity const& other) {
return this->getGlobalBounds().intersects(other.getGlobalBounds());
}
};
class Player : public Entity {};
class Zombie : public Entity {};
int main() {
Player player;
player.setPosition({ 200, 200 });
player.setSize({ 100, 100 });
Zombie enemy;
enemy.setPosition({ 151, 151 });
enemy.setSize({ 50, 50 });
std::cout << player.isColliding(enemy);
}

How to solve this C++ multiple inheritance similar issue

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);
};

Derive Smiley from Circle

I am trying to derive class Smiley from Circle:
struct Smiley : Circle {
void draw_lines() const;
};
void Smiley::draw_lines() const {
Circle::draw_lines(); // outline
/*rest of code here*/
}
This is the definition of Circle:
struct Circle : Shape {
Circle(Point p, int rr); // center and radius
void draw_lines() const;
Point center() const;
void set_radius(int rr) { set_point(0, Point(center().x - rr, center().y - rr)); r = rr; }
int radius() const { return r; }
private:
int r;
};
I basically want a Circle with a couple arcs drawn on top. Theoretically, I should only have to write draw_lines() over (which is defined as virtual in Shape), but it does nothing without a constructor, and if I have a constructor, it get an error and says that Circle does not have a default constructor available, even if I have no code in the constructor relating to Circle.
Does anyone know why I am getting this error?
When you inherit from a class with no default constructor, you have to make sure you invoke the non-default one.
Otherwise your derived class tries to invoke that non-existent default constructor, as the error says. In this case, you can probably just pass the same arguments straight through.
struct Smiley : Circle {
Smiley(Point p, int rr);
void draw_lines() const;
};
Smiley::Smiley(Point p, int rr)
: Circle(p, rr)
{};
I basically want a Circle with a couple arcs drawn on top
Then it's not a circle any more, so why does Smiley inherit Circle?
You've defined a constructor for circle that requires a Point and a Radius. You should define one with identical parameters for Smiley, that invokes the base class constructor with those parameters, via a Member Initialiser List.
struct Smiley : Circle {
Smiley(Point p, int rr) : Circle(p, rr)
{
}
void draw_lines() const;
};

I keep getting an error when I use this code. I'm trying to use constructors in an inherited class. c++

So, my problem is I don't really know a lot about classes. So, I am trying to get this constructor to work. I need the base constructor and the constructor of the derived class to work without implementing it there. I can define it there i just can't implement it. The compiler is telling me it's expecting a curly brace.
#ifdef SHAPE.H
#endif SHAPE.H
#define
#include<string>
using namespace std;
class QuizShape
{
private:
char outer, inner;
string quizLabel;
public:
//Constructor
QuizShape();
};
class Rectangle : public QuizShape
{
public:
int height, width;
//Getter & setter methods
int getHeight() const;
void setHeight(int);
int getWidth() const;
void setWidth(int);
//Constructor for Rectangle
Rectangle() : QuizShape();
};
class Square : public Rectangle
{
public:
//constructors
Square() : Rectangle (); This area here is where the error comes // IT says it expects a { but I'm not allowed to define the constructor in line.
Square(int w, int h) : Rectangle (height , width);
};
class doubleSquare : public Square
{
//Fill in with constructors
};
I don't understand the error it's giving me. I'm pretty sure I'm not redefining it either.
The constructor needs to be defined. Pls observe the changes in the way constructors are defined/used.
#include<string>
using namespace std;
class QuizShape
{
private:
char outer, inner;
string quizLabel;
public:
//Constructor
QuizShape();
};
class Rectangle : public QuizShape
{
public:
int height, width;
//Getter & setter methods
int getHeight() const;
void setHeight(int);
int getWidth() const;
void setWidth(int);
//Constructor for Rectangle
Rectangle() { }
Rectangle(int h, int w): height(h), width(w) { }
};
class Square : public Rectangle
{
public:
//constructors
Square() { } //
Square(int w, int h) : Rectangle (h, w) {}
};
class doubleSquare : public Square
{
//Fill in with constructors
};
Move your constructor initializer lists to the definitions. For example, for Square:
//declarations
Square();
Square(int w, int h);
//definitions
Square() : Rectangle() {/*body*/}
Square(int w, int h) : Rectangle(w, h) {/*body*/} //assuming you meant w, h
Do that for the other constructors with initializer lists in the declarations as well.