Правильный способ вернуть умный указатель от члена класса? - PullRequest
0 голосов
/ 05 мая 2018

Я пытаюсь написать шаблон синглтона в классе person, который дает мне возможность создать только один экземпляр для этого класса, и я могу использовать его в любом месте моей программы.

Ниже приведен класс:

// 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;
}

Но проблема в том, что он дает мне эту ошибку: 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

К сожалению, я не понимаю этой проблемы и не знаю, как ее решить?

1 Ответ

0 голосов
/ 05 мая 2018

Конструктор копирования std::unique_ptr неявно удаляется, поскольку у него есть явно определенный конструктор перемещения.

Из C ++ 11 Standard, 12.8 Копирование и перемещение объектов класса :

7 Если определение класса явно не объявляет конструктор копирования, он объявляется неявно . Если определение класса объявляет конструктор перемещения или оператор присваивания перемещения, неявно объявленный конструктор копирования определяется как удаленный; в противном случае он определяется как значение по умолчанию ( [dcl.fct.def] ).

Вы можете решить свою проблему:

  1. Возврат ссылки на Person.

    static Person& getInstance();
    
    
    Person& Person::getInstance()
    {
       static Person p;
       return p;
    }
    
  2. Возвращает 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;
    }
    

Я рекомендую первое решение, поскольку оно проще.

PS Обратите внимание, что ни один из них не требует использования static переменной-члена instance.

...