Lion King
Lion King

Reputation: 33813

The right way to return a smart pointer from a class member?

I am trying to write the singleton pattern in the person class which gives me the ability to create just one instance for that class and I can use it in any place in my program.

The following is the class:

// The declaration
class Person {
    static unique_ptr<Person> instance;
    Person() = default;
    Person(Person&) = delete;
    Person& operator=(const Person&) = delete;
    ~Person() = default;
public:
    static unique_ptr<Person> getInstance();
};

// The implementation   
unique_ptr<Person> instance = NULL;
unique_ptr<Person> Person::getInstance() {
    if (instance == NULL) {
        instance = unique_ptr<Person>(new Person());
    }
    return instance;
}

But the problem that it gives me this error: Error C2280 'std::unique_ptr<Person,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function

Unfortunately, I don't understand that problem and I don't know how to solve?

Upvotes: 0

Views: 742

Answers (1)

R Sahu
R Sahu

Reputation: 206637

The copy constructor of std::unique_ptr is implicitly deleted since it has an explicitly defined move constructor.

From the C++11 Standard, 12.8 Copying and moving class objects:

7 If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted ([dcl.fct.def]).

You can solve your problem by:

  1. Returning a reference to a Person.

    static Person& getInstance();
    
    
    Person& Person::getInstance()
    {
       static Person p;
       return p;
    }
    
  2. Returning a shared_ptr<Person>.

    static std::shared_ptr<Person> getInstance();
    
    
    std::shared_ptr<Person> Person::getInstance()
    {
       static std::shared_ptr<Person> p(new Person);
       return p;
    }
    

I recommend the first solution since it is simpler.

PS Please note that neither of them requires use of the static member variable instance.

Upvotes: 6

Related Questions