如何在构造函数中为成员 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 赋予默认值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 的外部类构造函数中初始化嵌套类成员

如何在构造函数中使用删除器初始化 std::unique_ptr?

如何在 C++ 中为矩阵类型构建构造函数

如何初始化一个unique_ptr

GroovyGroovy 方法调用 ( Groovy 构造函数中为成员赋值 | Groovy 函数的参数传递与键值对参数 | 完整代码示例 )

如何将非静态成员函数作为unique_ptr删除器传递[重复]