I’m programming a basic graphic scene editor with OpenGL and C++, and this is the context:
-
I have a Drawable class, which is abstract and has only one pure virtual function draw(). I’m using this class like a java interface.
-
Many classes that inherit from Drawable and reimplement draw().
-
A Scene class which contains a list of pointers to Drawables.
-
The main.cpp where I create that differents Drawable objects and add them to the list.
I’m having this issues:
-
Created objects in main.cpp constantly going out of scope, so it’s not just easy as creating them and executing the adding function with a referenced object. (Just keeping a list with no valid pointers all the time).
-
A bittersweet solution is creating these new objects with new and letting the Scene class deleting the pointers in the list when it is destroyed, or deleting them in main.cpp somehow.
I don’t really like this so I want to ask if there is some method to copy the objects inside the add function and then store the copy in the list, which it’s not a problem because the copied object it’s going to erase soon. Inside that function I don’t know which subclass of Drawable I’m attending. I can’t make a copy directly of the Drawable object because Drawable is an abstract class, can’t make Drawable objects with new for the same. Just want to have a list with different objects which all can execute draw(). I leaving some code just in case:
class Drawable {
public:
virtual void draw() = 0;
virtual ~Drawable() = 0 {}
};
class Figure : public Drawable {
private:
list<Point, allocator<Point>> _points;
int _type;
public:
...
void draw() {
...
}
};
class Scene : public Drawable {
private:
list<Drawable*, allocator<Drawable*>> _drawables;
...
public:
...
void add(Drawable* drawable) {
_drawables.push_back(drawable);
}
~Scene() {
for(iterDrawable it = _drawables.begin(); it != _drawables.end(); ++it)
delete (*it);
}
void draw() {
for(iterDrawable it = _drawables.begin(); it != _drawables.end(); ++it)
(*it)->draw();
}
};
main.cpp
...
void display() {
...
Figure* square = new Figure(GL_POLYGON);
square->add(Point(xSquare, ySquare));
square->add(Point(xSquare + squareWidth, ySquare));
square->add(Point(xSquare + squareWidth, ySquare + squareHeight));
square->add(Point(xSquare, ySquare + squareHeight));
cScene.add(square);
cScene.draw();
...
}
...
I hope I explained sufficiently.
Drawablemust have a virtual destructor.deletethe list of its components before it itself goes away (that is, in the destructor). If the scene object is not the owner, and merely a user, then who is the owner? Can you guarantee that the owner will outlive all users? If not, how the owner will pass ownership to the next owner? If you are going to copy an object, you must decide this question for the original and for the copy.shared_ptrandptr_listare fine and dandy, but I suggest learning the basics first. It is important to understand whyshared_ptrandptr_listare needed, which problems they purport to solve, and what their solutions look like from 30000 feet. The best way to acquire such understanding is by stumbling upon, and trying to solve, some of these problems.Drawablemust have a virtual destructor.draw()for each derived class. The commonly accepted name for such a function isclone. For each classFoo,clonewould look like this:virtual Foo* clone() {return new Foo(*this);}Versions of
clonelook almost identically for all classes, nevertheless you do have to write each one of them manually. Note that this is usingFoo‘s copy constructor, which you will have to write yourself ifFooowns any other object, or has a copy operation that is non-trivial in some other way.Drawablemust have a virtual destructor?