-2

I'm trying to learn the kinds of factory patterns I can use in C++. I'm not sure why I can't return a unique ptr. I can return a shared ptr just fine. Here's my code:

class FactoryMethodExample {
    FactoryMethodExample() {}
public:
    static FactoryMethodExample get_instance() {
            return {};
    }

    static FactoryMethodExample * get_pointer() {
        return new FactoryMethodExample;
    }

    static unique_ptr<FactoryMethodExample> get_unique_instance() {
        return make_unique<FactoryMethodExample>();
    }

    static shared_ptr<FactoryMethodExample> get_shared_instance() {
        return shared_ptr<FactoryMethodExample>();
    }

    void verify() {
        cout << "I exist" << endl;
    }
};

This code doesn't compile. I get this error :

error: calling a private constructor of class 'FactoryMethodExample'
return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
Behrooz Karjoo
  • 4,250
  • 10
  • 38
  • 48
  • 4
    `make_unique` cannot use a private constructor: it's not a friend of the class. You'd have to do the old-fashioned `return std::unique_ptr(new FactoryMethodExample());` – Igor Tandetnik Jun 02 '17 at 03:45
  • 5
    Also note that your `get_shared_instance()` doesn't actually return an instance - it returns a null shared pointer. – Igor Tandetnik Jun 02 '17 at 03:48
  • use `return std::make_shared()` (after making the constructor accessible) if you have `std::make_shared()` available, otherwise use `return shared_ptr(new FactoryMethodExample);` – Remy Lebeau Jun 02 '17 at 04:20
  • @IgorTandetnik thanks, your old-fashioned way worked. However I was not able to make it work via the friend class method. Can you shed some light on that? – Behrooz Karjoo Jun 02 '17 at 13:18
  • 1
    Don't do that; it's non-portable. Even if you manage to befriend `std::make_unique`, it could legally delegate the actual work to some internal helper function (which wouldn't be a friend, leaving you right where you started). So your program would compile with some standard library implementations but not others. – Igor Tandetnik Jun 02 '17 at 17:05

1 Answers1

1

Firstly, your shared_ptr and unique_ptr examples are not comparable.

make_unique creates a unique_ptr initialised with a value.

shared_ptr is just a constructor call of the shared_ptr class, which will leave it initialised with a null pointer.

This is why you are getting two different results.

The reason you have an error, is because you have a private constructor. The easiest solution is to make make_unique (and make_shared) friends.

See the following question for a bit of guidance: How to make std::make_unique a friend of my class

In addition, your function names may be misleading. get_shared_instance implies that the same instance will be returned every time, where I think you want to return a shared_ptr of a new instance?

Ajay
  • 18,086
  • 12
  • 59
  • 105
Gregory Currie
  • 607
  • 4
  • 14