【问题标题】:The right way to return a smart pointer from a class member?从类成员返回智能指针的正确方法?
【发布时间】:2018-05-04 22:13:56
【问题描述】:

我正在尝试在 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&lt;Person,std::default_delete&lt;_Ty&gt;&gt;::unique_ptr(const std::unique_ptr&lt;_Ty,std::default_delete&lt;_Ty&gt;&gt; &amp;)': attempting to reference a deleted function

很遗憾,我不明白那个问题,也不知道如何解决?

【问题讨论】:

  • 您希望从返回 unique_ptr&lt;Person&gt;Person&amp; 不会提供给您的信息中得到什么? unique_ptr 中的 "unique" 表示尝试复制它将失败。
  • std::unique_ptr 有一个明确删除的复制构造函数。不能复制,但是可以参考*uniquePtr或者移动std::unique_ptr
  • @Justin 想想如果你 move 单身会发生什么。
  • @user4581301 我很清楚会发生什么。我正在给 OP 直接翻译错误消息
  • 这是正确方法可能是做其他事情的情况之一。这是一个关于更好替代方案之一的精彩文章的链接:stackoverflow.com/a/1008289/4581301

标签: c++ c++11 singleton smart-pointers


【解决方案1】:

std::unique_ptr 的复制构造函数被隐式删除,因为它具有显式定义的移动构造函数。

来自C++11 Standard, 12.8 Copying and moving class objects

7 如果类定义没有显式声明复制构造函数,则隐式声明。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数定义为已删除;否则,它被定义为默认值 ([dcl.fct.def])。

您可以通过以下方式解决您的问题:

  1. 返回对Person 的引用。

    static Person& getInstance();
    
    
    Person& Person::getInstance()
    {
       static Person p;
       return p;
    }
    
  2. 返回一个shared_ptr&lt;Person&gt;

    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

【讨论】:

  • 抱歉,最后一行是什么意思?
  • @LionKing 表示可以从Person类声明中删除instance成员变量(即删除这行代码:static unique_ptr&lt;Person&gt; instance;
  • @RemyLebeau:谢谢。
  • 我希望我能不止一次地提出这个答案
猜你喜欢
  • 1970-01-01
  • 2015-06-12
  • 2013-03-16
  • 2014-05-30
  • 2015-05-24
  • 2018-03-22
  • 1970-01-01
  • 1970-01-01
  • 2011-12-25
相关资源
最近更新 更多