0

Basically, this:

Cat CatFactory::CreateCat()
{
    return Cat();
}

or this:

Cat* CatFactory::CreateCat()
{
    return new Cat();
}

I know the general advice is to avoid new when possible and tend to prefer object creation on the stack so one doesn't have to use delete. Does that apply to factories as well? All the examples I see tend to use the new keyword. Why is this the case?

I can't use smart pointers because this is a class project and everyone is new to C++ and we have to integrate our projects later.

  • return Cat(); returns a local object, which as soon as it goes out of scope will result in undefined behavior when using it :) You return by value, so you get a local copy again at the calling code, but i would not recommend it.. – cageman Oct 15 '14 at 17:21
  • 1
    @cageman that isn't correct at all. `return Cat();` will return by-value, invoking the copy-ctor (with a very high probability even that will elide due to [**RVO**](http://en.wikipedia.org/wiki/Return_value_optimization)). There is no UB in the first sample. – WhozCraig Oct 15 '14 at 17:32
  • Your correct, thanks for the headsup. – cageman Oct 15 '14 at 17:36

2 Answers2

4

All the examples I see tend to use the new keyword. Why is this the case?

Because the factory pattern is typically used to avoid leaking knowledge of the constructor and the class hierarchy (an implementation detail in many systems!) to the caller; you want to employ it if you're going to return an instance of a subclass of Cat rather than a Cat:

Cat *make_cat(int type)
{
    switch (type) {
        case TABBY:
            return new Tabby();
        case TORTOISESHELL:
            return new Tortoiseshell();
        // etc.
    }
};

You can't do this if you return by value.

Other reasons for returning by value include non-copyable objects. If you don't like using raw pointers, and modern C++ style has it that you should, return a unique_ptr or shared_ptr instead.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • One more reason is memory management. Often factory is a part of library interface, and used to implement [COM style](http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL#CppMatureApproach) interface. – magras Oct 15 '14 at 17:32
0

It all depends on what do you mean by "object" (in abstarct sense) in you application context, and how do you identify it, and the role that polymorphism must have respect to it.

If your object are not required to be polymorphic, and you can identify them by value, you can pass them by value (or "move" them, in C++11) so -in fact- you can use a "value sematics". In this context, two variables both containing "abc" are "equal" and considered to represent "the same thing" in different places (scopes).

If you identify objects by their position in memory (a.k.a. address) than you have to pass pointers or references, so that no copy is made. In this context two different variables both containing "abc" are considered "representing different things, that incidentally looks the same".

If polymorphism is required, then, pass by pointer (or by reference, but not by value) is a must, since C++ polymorphism is operated by means of indirection.

OOP based programs tend to follow the second paradigm. Functional or generic programs tend to follow the first.

The main point, here, is that the "factory pattern" is an OOP technique, not that interesting outside the OOP world.

Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63