unique_ptr创建澄清

时间:2014-05-03 17:16:57

标签: c++ unique-ptr

这是使用XCode C ++语言方言c ++ 1y。帮我理解unique_ptr:

//1

    auto ouput2 = make_unique<standard::Algorithm>(AlgorithmFactory::create("YamlOutput",
                                                                               "filename", outputFilename));

//2

    unique_ptr<standard::Algorithm> output(standard::AlgorithmFactory::create("YamlOutput",
                                                                                  "filename", outputFilename));

1失败,构建时出现“语义问题:分配抽象类类型的对象'essentia :: standard :: Algorithm',但是2成功。

read这两个是等价的,那么怎么会成功而另一个不成功呢?

我查看AlgorithmFactory :: create()的源代码,它根据字符串输入返回BaseAlgorithm *。因为标准:: Algorithm似乎与BaseAlgorithm没有任何关系(它没有扩展它),所以并不真正理解对象层次结构。

这就是我使用的Essentia库的文档是如何做到的,除非他们使用的是裸指针。

3 个答案:

答案 0 :(得分:4)

它们并不等同。 make_unique创建对象,而unique_ptr只包含现有指针。

您的第一行相当于unique_ptr<standard::Algorithm>(new standard::Algorithm(AlgorithmFactory::create(...)))。请注意此处使用new

答案 1 :(得分:3)

这两个陈述并不等同。区别在于:

  • 您的第二个版本是通过提供现有的原始指针来调用unique_ptr构造函数。它只将该对象指针封装在unique_ptr

  • 第一个版本应该为您的对象提供构造函数参数,它将以安全的方式为您创建对象。它构造并封装了unique_ptr

  • 中的对象

问题是您的工厂已经分配了对象并返回一个原始指针。那时使用make_unique就没有意义,因为该函数的目的是避免完全处理原始指针,即一次性构造和包装。

这里有两个选项:

  1. 坚持你的第二个版本。

  2. 更改工厂,使其在其实施中使用unique_ptr返回make_unique。但是提供同一工厂的shared_ptr版本也是有意义的。像createUnique + createShared这样的东西,也许保留现有的create返回原始指针。这是代码风格的问题。

答案 2 :(得分:1)

std::make_unique<T>将其参数转发给T的构造函数并构造一个新的T,然后创建一个指向新构造的std::unique_ptr<T>的{​​{1}}。如果T是一个抽象类,那么这肯定会失败。即使T不是抽象类,也可能无法编译,因为T函数可能会返回AlgorithmFactory::create。另一方面,T*的构造函数采用可转换为std::unique_ptr<T>的参数,并且没有问题。