6

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 ?

3
  • 8
    Why do you think you can move something, and then use the stub that is left to move again? Think of moving like the literal action, you only move out of a house once. (well unless you move back in but the analogy still holds) Commented Feb 13, 2020 at 13:56
  • 1
    It's not really any pointers that are unique but the underlying objects, in the sense that every object always has exactly one owner. ("uniquely_owned" would be a more descriptive name than "unique_ptr".) If you hand over ("move") the object to a different owner, the original owner no longer has possession of the object. Commented Feb 13, 2020 at 14:10
  • The code is working properly, exactly as programmed. And may I say, it is also nicely formatted. Commented Feb 13, 2020 at 14:36

2 Answers 2

14

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.

Sign up to request clarification or add additional context in comments.

Comments

0

Pointer1 ownership is already transferred to vector[0]. so resources pointed to by pointer1 is no longer valid and then again set with the same inside if loop. So that will be a null only i guess.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.