C ++ Вектор практики уникальных указателей - PullRequest
5 голосов
/ 13 февраля 2020

Прежде всего, вот мой код:

#include <iostream>
#include <memory>
#include <vector>

class Animal 
{

public:

    virtual void display() =  0;

};

class Dog : public Animal 
{
    std::string name;

public:

    Dog(std::string n) : name(n) {}

    void display() override
    {
        std::cout << "I'm a dog and my name is: " << name << std::endl;
    }

};


class Cat : public Animal 
{
    std::string name;

public:

    Cat() {}
    Cat(std::string n) : name(n) {}

    void display() override
    {
        std::cout << "I'm a cat and my name is: " << name << std::endl;
    }

};


int main()
{
    Dog D1("Spike");
    Dog D2("Razor");
    Cat C1("Cat");

    std::vector<std::unique_ptr<Animal>> vectorOfAnimals;

    std::unique_ptr<Animal> pointer1 = std::make_unique<Dog>(D1);
    std::unique_ptr<Animal> pointer2 = std::make_unique<Dog>(D2);
    std::unique_ptr<Animal> pointer3 = std::make_unique<Cat>(C1);
    std::unique_ptr<Animal> pointer4 (nullptr);

    vectorOfAnimals.push_back(std::move(pointer1));
    vectorOfAnimals.push_back(std::move(pointer2));
    vectorOfAnimals.push_back(std::move(pointer3));
    vectorOfAnimals.push_back(std::move(pointer4));

    for(auto& animals : vectorOfAnimals)
    {
        animals = nullptr;
    }

    if(!vectorOfAnimals[0])
    {
        std::cout << "First element is nullptr!" << std::endl;
        vectorOfAnimals[0] = std::move(pointer1);
    }

    for(auto& animals : vectorOfAnimals)
    {
        if(!animals)
        {
            std::cout << "This is a nullptr!" << std::endl;
        }
        else
        {
            animals->display();
        }
    }

    return 0;
}

Я создал абстрактный класс с 2 производными классами. Затем отодвинул несколько уникальных указателей в векторе уникальных указателей на базовый класс. Затем для целей обучения я присвоил всем элементам вектора nullptr и попытался передать владение первым указателем, созданным с именем «pointer1», первому элементу вектора, но это не работает, первый элемент остается нулевым. Где я не прав?

Ответы [ 2 ]

12 голосов
/ 13 февраля 2020

std::move - это не то, что вы делаете, просто чтобы ваш код компилировался. На самом деле у него есть функция, цель, результат. *

В результате ваши данные были удалены. Это прошло. Сейчас в контейнере; pointer1 et c остаются не связанными с указателями в векторе и (что более важно) больше не указывают ни на что.

Таким образом, это не имеет смысла:

vectorOfAnimals[0] = std::move(pointer1);

Подумайте о слове «уникальный» в названии unique_ptr.


* std::move само по себе ничего не двигает. Но для наших сегодняшних целей достаточно близко.

0 голосов
/ 13 февраля 2020

Владение Pointer1 уже передано в вектор [0]. поэтому ресурсы, на которые указывает pointer1, больше не действительны, а затем снова установлены с тем же внутренним значением, если l oop. Так что это будет ноль, только я думаю.

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