Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Storing specific shapes(circle, rect) in a pointer to sf::Shape  (Read 2229 times)

0 Members and 1 Guest are viewing this topic.

neondrop

  • Newbie
  • *
  • Posts: 1
    • View Profile
I have a class called Actor which is intended to represent both rectangles and circles in my application. The class contains a member sf::Shape *mShape in which either a new sf::CircleShape or sf::RectShape is stored on construction of the object. My first question would be if this is actually the best approach or if I should make two extra classes for rectangles and circles that derive from Actor. I thought about this, but I first wanted to try it with one class since I didn't want to bloat the code with so much classes if I can avoid it, and also its easier to just loop through a vector of one class type. This approach worked fine until I needed to pass the mShape of an Actor to a function that specifically requires a pointer to sf::CircleShape and sf::RectangleShape. Here is some code:
class Actor : public sf::Transformable, public sf::Drawable {
    public:
    sf::Shape* mShape;

    Actor(float radius) {
        mShape = new sf::CircleShape(radius);
        //do stuff
    }

    Actor(float width, float height) {
        mShape = new sf::RectangleShape(sf::Vector2f(width, height));
        //do stuff
    }

    private:
    virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const {
        target.draw(*mShape, states);
    }
};

void foo(sf::CircleShape* circle, sf::RectangleShape* rect) {
    //do stuff
}

void moveActors() {
    foo(actors[0].mShape, actors[1].mShape);  
}
 
It doesn't work how I intend it to, which may be obvious to someone who has a deeper understanding of pointers and class inheritance than me. The compiler complains that conversion from sf::Shape* to sf::CircleShape* or sf::RectangleShape* is invalid.So my second question would be I should best go about this. I realize that the problem may lie in my understanding of C++ and pointers, but I hope it's specific enough to SFML that I can ask here.
« Last Edit: November 10, 2018, 03:27:31 am by neondrop »

NGM88

  • Full Member
  • ***
  • Posts: 162
    • View Profile
Re: Storing specific shapes(circle, rect) in a pointer to sf::Shape
« Reply #1 on: November 10, 2018, 01:20:49 pm »
Any RectShape or CircleShape will be the victim of object slicing if you try to access them via Shape*. Wrapping those shapes in a class that properly utilizes virtual functions would fix this problem.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Storing specific shapes(circle, rect) in a pointer to sf::Shape
« Reply #2 on: November 10, 2018, 08:34:03 pm »
Quote
Any RectShape or CircleShape will be the victim of object slicing if you try to access them via Shape*
That's not true. Slicing would occur with a sf::Shape (ie. a copy). And it has nothing to do with the problem, which is that downcasting requires an explicit dynamic_cast (or better: should be avoided) ;)
Laurent Gomila - SFML developer

NGM88

  • Full Member
  • ***
  • Posts: 162
    • View Profile
Re: Storing specific shapes(circle, rect) in a pointer to sf::Shape
« Reply #3 on: November 11, 2018, 08:00:34 am »
I guess that's why it's not called "pointer slicing"!  :(

 

anything