从类成员返回智能指针的正确方法?
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<Person,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function
很遗憾,我不明白那个问题,也不知道如何解决?
【问题讨论】:
您希望从返回unique_ptr<Person>
而 Person&
不会提供给您的信息中得到什么? 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<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
。
【讨论】:
抱歉,最后一行是什么意思? @LionKing 表示可以从Person
类声明中删除instance
成员变量(即删除这行代码:static unique_ptr<Person> instance;
)
@RemyLebeau:谢谢。
我希望我能不止一次地提出这个答案以上是关于从类成员返回智能指针的正确方法?的主要内容,如果未能解决你的问题,请参考以下文章