C++ unique_ptr 初始化

Bat*_*rka 0 c++ initialization

我有问题。让我们看一下这段代码:

#include <iostream>
#include <string>
#include <memory>

class Writable {
public:
    virtual ~Writable() = default;
    virtual void write(std::ostream& out) const = 0;
};

class String : public Writable {
public:
    String(const std::string& str) : m_str(str) {}
    virtual ~String() override = default;
    virtual void write(std::ostream& out) const override { out << m_str << '\n'; }
private:
    std::string m_str;
};

class Number : public Writable {
public:
    Number(double num) : m_num(num) {}
    virtual ~Number() override = default;
    virtual void write(std::ostream& out) const override { out << m_num << '\n'; }
private:
    double m_num;
};

int main() {
    std::unique_ptr<Writable> str1(new String("abc"));
    std::unique_ptr<Writable> num1(new Number(456));

    str1->write(std::cout);
    num1->write(std::cout);
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么 unique_pointers 是这样定义的:

std::unique_ptr<Writable> str1(new String("abc"));
Run Code Online (Sandbox Code Playgroud)

它是某种简写吗?或者我必须这样做?有某种等价物吗?例如:

std::unique_ptr<Writable> str1 = std::unique_ptr<String>(new String("abc"));
Run Code Online (Sandbox Code Playgroud)

bal*_*lki 6

在这里,您将创建一个新对象unique_ptr并使用new运算符返回的原始指针进行初始化。

std::unique_ptr<Writable> str1(new String("abc"));
Run Code Online (Sandbox Code Playgroud)

在这里,您将创建一个新的unique_ptr并使用运算符返回的原始指针进行初始化new,然后用它构建另一个unique_ptr

std::unique_ptr<Writable> str1 = std::unique_ptr<String>(new String("abc"));
Run Code Online (Sandbox Code Playgroud)

但是,编译器(很可能)可以执行 move elison 并使上述两者等效。

从 C++14 及更高版本初始化的正确方法如下

std::unique_ptr<Writable> v1 = std::make_unique<String>();
Run Code Online (Sandbox Code Playgroud)