Инициализация C ++ unique_ptr - PullRequest
       0

Инициализация C ++ unique_ptr

0 голосов
/ 11 декабря 2018

У меня есть вопрос.Давайте получим следующий код:

#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"));

Ответы [ 3 ]

0 голосов
/ 11 декабря 2018

Здесь вы создаете новый 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>();
0 голосов
/ 11 декабря 2018

Так же, как вы можете написать

std::vector<int> foo(10);

, чтобы создать вектор из 10 int s

std::unique_ptr<Writable> str1(new String("abc"))

, создающий std::unique_ptr<Writable>, который указывает на new String("abc").Это то же самое, что и

std::vector<int> foo = std::vector(10);

и

std::unique_ptr<Writable> str1 = std::unique_ptr<String>(new String("abc"));

, за исключением того, что в более поздних случаях используется инициализация копии , которая в некоторых случаях может отличаться .


Чтобы сэкономить на наборе текста, вы можете использовать

auto str1 = std::make_unique<String>("abc");

вместо того, чтобы объявить свои unique_ptr '

0 голосов
/ 11 декабря 2018

Форма инициализации в

std::unique_ptr<Writable> str1(new String("abc"));

называется прямой инициализацией .Если конструктор помечен explicit (как в конструкторе explicit unique_ptr(pointer p) noexcept), требуется эта форма инициализации.

explicit конструктор отключает копия инициализации в виде std::unique_ptr<Writable> str1 = new String("abc");.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...