I am making a simple 2D physics engine for circles and squares. I have a body class that I want to be given a unique_ptr instance of a shape when created. The shape can either be a circle or a box. The body is the object that I want to throw into my game loop to check for collisions. When checking for collisions, I am interested in the data associated with the shapes. A very primitive example is shown below:
#include <iostream> #include <memory> struct Shape { virtual float calculateArea() const = 0; }; struct Circle: public Shape { const float m_radius; Circle(float radius) : m_radius(radius) {} float calculateArea() const {return m_radius*m_radius*3.14;} }; struct Square: public Shape { const float m_side_length; Square(float side_length) : m_side_length(side_length) {} float calculateArea() const {return m_side_length*m_side_length;} }; struct Body { Body(std::unique_ptr<Shape>& shape): m_shape(std::move(shape)) {} std::unique_ptr<Shape> m_shape; }; int main() { std::unique_ptr<Shape> circ = std::make_unique<Circle>(5.0); std::unique_ptr<Shape> square = std::make_unique<Square>(10.0); std::shared_ptr<Body> body1 = std::make_shared<Body>(circ); std::shared_ptr<Body> body2 = std::make_shared<Body>(square); } Essentially, I am wondering if there is a way to access the radius of a shape or the side length of a shape. I can see that something like
body1->shape->m_radius or body2->shape->m_side_length doesn't work but I really want to find a solution where my shapes can be grouped into a general shape class and I'm still able to access their unique features through the body class. This is for collision detection btw.
I saw some related posts such as here: Access members of derived class through base class pointer C++ but the overall problem is slightly different from mine and the question is quite old.
Thanks for the help - hope it makes sense!
virtualfunctions. A base class knows nothing about any derived classes, and cannot as a new derived class can be added years after the base class was last compiled. But if it containsvirtualfunctions, the derived classes can override those functions and take more specific actions, operating on its member variables and perhaps returning them.shapeto have a radius because most shape-derived classes will not have a radius. If you need to get this information from a shape, inheritance is not the right tool, at least not atshapelevel. Also see the example of the rectangle vs the square in the Liskov link given above.