如何在构造函数中为成员 unique_ptr 赋予默认值? [复制]
Posted
技术标签:
【中文标题】如何在构造函数中为成员 unique_ptr 赋予默认值? [复制]【英文标题】:How to give a default value to a member unique_ptr in constructor? [duplicate] 【发布时间】:2013-07-27 22:55:15 【问题描述】:例如,我有一个班级
class A
public:
// argument with default value is too long, any better way
A(std::unique_ptr<int> data = std::unique_ptr<int>(new int(10)))
: mData(std::move(data))
// Is r-value better? Is the following code okay?
A(std::unique_ptr<int>&& data = std::unique_ptr<int>(new int(10)))
: mData(data)
private:
std::unique_ptr<int> mData;
;
【问题讨论】:
你可以有一个默认构造函数:A(): mData(new int(10))
您想要更短的代码吗?第二个构造函数将只接受 r 值,数据将被复制,而不是像在第一个构造函数中那样显式移动到 mData
【参考方案1】:
乍一看,似乎可以这样做:
A (std::unique_ptr<int> data = new int(10))
: mData(std::move(data))
注意花括号的使用(即统一初始化。)但是,这不起作用(不编译,)因为unique_ptr
构造函数接受一个指针被声明为explicit
,这排除了它在这里的使用。
您还可以这样做:
A (int * data = new int(10))
: mData (data)
也就是说,接受一个普通的指针并从中构造你的成员。而且您也不需要离开它(不过仍然建议使用std::move
。)
这个确实可以编译并且可以工作,但是它有一个致命的缺陷,即尽管您正在接管传入指针的所有权(您将转到 delete
它),但您并没有在界面中显示此行为.因此,这个新界面将比以前的界面提供更少的信息。
还有一种方法是写一个快捷函数模板,像这样:
template <typename T>
std::unique_ptr<T> uptr (T * v)
return std::unique_ptr<T>(v);
然后,你的构造函数变成:
A(std::unique_ptr<int> data = uptr(new int(10)))
: mData(std::move(data))
但在我看来,这并没有太大的改进。
但是,如果这个特定用例是您的全部问题,为什么不直接定义一个默认构造函数和一个单参数构造函数,如下所示:
A ()
: mData (new int (10))
/*explicit*/ A (std::unique_ptr<int> data)
: mData(std::move(data))
这更明智。 (请注意,将explicit
放在那里是一个好主意和好形式,但与您的问题无关,因此我已将其注释掉。)
另外,你的第二个构造函数实际上并没有移动任何东西。在这种情况下,r 值引用类型不像您认为的那样工作。简而言之,既然data
有了名字,它就不再是一个右值,尽管它的类型仍然是对某事物的右值引用。
【讨论】:
uptr
应替换为 std::make_unique
以上是关于如何在构造函数中为成员 unique_ptr 赋予默认值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何在构造函数中使用删除器初始化 std::unique_ptr?
GroovyGroovy 方法调用 ( Groovy 构造函数中为成员赋值 | Groovy 函数的参数传递与键值对参数 | 完整代码示例 )