Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Vector of unique pointers practice

First of all, here is my code:

#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;
}

I created an abstract class with 2 derived classes. Then, pushed backed some unique pointers in a vector of unique pointers to base class. For learning purposes, then, I assigned to all elements of vector nullptr and tried to transfer ownership of first pointer created called "pointer1" to first element of vector, but it doesn't work, first element remains nullptr. Where I'm wrong ?

like image 340
Razvan Nechita Avatar asked Feb 13 '20 13:02

Razvan Nechita


1 Answers

std::move is not something you do just to get your code to compile. It actually has a function, a purpose, a result.*

The result is that your data has been moved away. It's gone. It's in the container now; pointer1 etc remain unconnected to the pointers in the vector, and (more importantly) no longer point to anything.

As such, this makes no sense:

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

Think about the word "unique" in the name unique_ptr.


* std::move itself doesn't actually move anything. But, for our purposes today, close enough.

like image 163
Asteroids With Wings Avatar answered Nov 10 '22 14:11

Asteroids With Wings