I'll respond to your private message here, so that others can read and participate as well.
First of, I read your article on RAII and even though I understood what it meant, I can't get my head around when to use and how to use it properly.
It's simple: use it always
What exactly don't you understand?
Second, you said :
Use std::unique_ptr if you need dynamic allocation (but try to avoid it in the first place!)
why should I try to avoid it?
I meant you should try to avoid dynamic allocations where possible. Often it's not necessary to use pointers or smart pointers, when automatic objects work fine. In this forum, code like
sf::RenderWindow window = new sf::RenderWindow(...);
// use the window
delete window;
is not uncommon. But it's simpler, shorter and safer to write
sf::RenderWindow window(...);
// use the window
In your case, I wondered why the factory returns a pointer to a tower and not a tower itself. Is it used polymorphically? For example, do you store a container of abstract entities rather than a container of towers?
And finally, could you point me in a direction of how would I modify my factory so that it uses RAII?
First, I would use a slightly different design. I'm no fan of global/static objects for convenience. When reflecting more about it, it's almost always possible to find a clear owner of an object, nothing just "needs to be there" (there are of course exceptions like logging).
Concretely, I would make the factory a member of an enclosing class (for example
World) that also contains the towers.
class TowerFactory
{
public:
// non-static member functions!
void registerTower(sf::Keyboard::Key id, TowerCreator func);
// if you use it polymorphically:
std::unique_ptr<Tower> create(sf::Keyboard::Key id) const;
// otherwise:
Tower create(sf::Keyboard::Key id) const;
private:
// object, not singleton function
std::map<sf::Keyboard::Key, TowerCreator> factories;
};
class World
{
...
private:
TowerFactory factory;
std::vector<Tower> towers;
};
One question is also, what advantage does the factory offer? Why not construct towers directly? One possible answer is that it gathers resources like textures, and passes references to the tower when constructing. That's also a flaw in your current design: you store a texture in each tower, duplicating the resource unnecessarily.
The tower itself might then consist of simply some logic attributes (such as hitpoints, position, rotation, target, range, ...). If you want, you can also add drawing-related functionality such as sprites. In the latter case, you should inherit
sf::Drawable rather than writing a custom
Draw() function. Also, you needn't redeclare empty virtual destructors, and you should avoid makîng member variables protected (encapsulate them as much as possible by making them private).
By the way, I've once gathered some reoccurring topics in
this thread, you might be interested in specific points from that list.