我有问题。我们来看看这段代码:
#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);
}
我不明白为什么为什么要这样定义unique_pointers:
std::unique_ptr<Writable> str1(new String("abc"));
是某种速记吗?还是我必须这样做?有某种等效物吗?例如:
std::unique_ptr<Writable> str1 = std::unique_ptr<String>(new String("abc"));
答案 0 :(得分:2)
这里您要创建一个新的unique_ptr
并使用new
运算符返回的原始指针进行初始化。
std::unique_ptr<Writable> str1(new String("abc"));
这里您要创建一个新的unique_ptr
并使用new
运算符返回的原始指针进行初始化,然后使用它来构造另一个unique_ptr
。
std::unique_ptr<Writable> str1 = std::unique_ptr<String>(new String("abc"));
但是,编译器可以(最有可能)执行移动elison并使上述两个等效。
从c ++ 14和更高版本初始化的正确方法如下所示:
std::unique_ptr<Writable> v1 = std::make_unique<String>();
答案 1 :(得分:1)
初始化形式
std::unique_ptr<Writable> str1(new String("abc"));
称为direct initialization。如果将构造函数标记为explicit
(类似于explicit unique_ptr(pointer p) noexcept
构造函数),则需要这种形式的初始化。
explicit
构造函数以std::unique_ptr<Writable> str1 = new String("abc");
的形式禁用copy initialization。
答案 2 :(得分:0)
就像你可以写
std::vector<int> foo(10);
创建10个int
的向量
std::unique_ptr<Writable> str1(new String("abc"))
创建一个指向std::unique_ptr<Writable>
的{{1}}。和做一样
new String("abc")
和
std::vector<int> foo = std::vector(10);
除了后面的情况使用复制初始化which can be different in some cases。
要节省某些输入,您可以使用
std::unique_ptr<Writable> str1 = std::unique_ptr<String>(new String("abc"));
相反,当您声明auto str1 = std::make_unique<String>("abc");
的时候