从类成员返回智能指针的正确方法?

Posted

技术标签:

【中文标题】从类成员返回智能指针的正确方法?【英文标题】: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 直接翻译错误消息 这是正确方法可能是做其他事情的情况之一。这是一个关于更好替代方案之一的精彩文章的链接:***.com/a/1008289/4581301。 【参考方案1】:

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

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

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

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

    返回对Person 的引用。

    static Person& getInstance();
    
    
    Person& Person::getInstance()
    
       static Person p;
       return p;
    
    

    返回一个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:谢谢。 我希望我能不止一次地提出这个答案

以上是关于从类成员返回智能指针的正确方法?的主要内容,如果未能解决你的问题,请参考以下文章

为啥即使从类内部获取成员函数指针值也需要类名限定?

使用std智能指针的正确方法来确保ptr安全

“指向成员的智能指针”的真实示例是啥?

从类指针向量创建成员变量向量

C ++从类外部设置指向结构中函数成员的指针

如何使用智能指针跟踪类的对象?