What's a good way of Factory's create method in c++11?

2k views Asked by At

Now I'm developing a c++ project. And I don't know what's a good way of c++ Factory's create method. My environment is below.

Environment:

  • gcc 4.8.2 g++
  • built with std=c++11 option

I've created a Item class its instances are created by MyFactoryClass.

class Item {
public:
  void hoge();
private:
  int fuga;
  string foo;
};

In this case, what's a good way to implement create method? In general later method is good, but I've heard RVO in recent c++. So do both ways are no problems? And if there are better ways, I'd love to hear your examples.

static Item createItem(int id);
static void createItem(int id, Item& item);
3

There are 3 answers

3
p.i.g. On

I think you should return a pointer to the Item

class MyFactoryClass final
{
public:
    static Item* create( const int aId );

private:
    MyFactoryClass();
};

or use a shared pointer.

std::shared_ptr< Item > create( const int aId );
0
Tony Delroy On

Returning the objects is fine:

static Item createItem(int id);

You're right that RVO can help, and it usually does, but even if in some case the optimiser didn't achieve TVO, it may fall back on move semantics which can still be acceptible. For example, given a std::string implementation supporting move semantics, the foo member will be initialised by moving rather than copy construction.

All up, returning by value is the more commonly recommended and used practice these days. It also means the caller doesn't to construct an object beforehand, which might be problematic if there's no appropriate constructor to create an object in a not-ready-for-use state (and when you can avoid giving classes constructors that leave them in such states, it encourages good localised RAII style).

NOTE: I am trusting that you do indeed want a factory as requested in the question, and do not actually want to use the factory method pattern to create instances of different types, albeit all derived from a common base.

0
iammilind On

If you want to create just an object then you may use following generic way which can be used for any class:

template<typename Class, typename... Args>
Class Create (Args&&... args)
{
  return Class(args...);  // RVO takes place here
}

Above is just an example, you may always modify it according to requirement. Demo.

Usage:

MyClass myClass = Create<MyClass>(Arg1, Arg2, Arg3);

However, this method is actually a wrapper upon constructor.