I do not think that the main purpose of the factory template is to "hide new from the client." The main goal is to "hide what new used and how." This gives you the freedom to choose in your implementation which class you will actually create.
For example, you can suggest a Renderer interface in a factory:
class Renderer { // ... }; struct RendererFactory { Renderer* createRenderer() const; }; Renderer* RendererFactory::createRenderer() const {
In C ++, the added benefit of providing a factory function is to ensure proper memory management. If you changed the code above to return std::unique_ptr<Renderer> (what needs to be done correctly), you protect the client from Murphying a memory leak (what they could do without calling delete on the return value in the case of an unhandled pointer) 1 .
You might want your factory to retain partial ownership of the object (so that it can reuse them), so you would do something like this:
class RendererFactory { std::weak_ptr<Renderer> cachedRenderer; public: std::shared_ptr<Renderer> createRenderer(); }; std::shared_ptr<Renderer> RendererFactory::createRenderer() { if (auto r = cachedRenderer.lock()) return r; auto r = std::make_shared<RendererSubClass>(); cachedRenderer = r; return r; }
To summarize, factory design patterns (Annotation factory and factory) give you more control over how creation and initialization work.
1 Of course, they can still Machiavelli leak memory by running createRenderer().release() , but then this is an active action on their part, and not just inaction.
source share