C/C++ Arena

Step 2 of 5

Unique means unique

"Unique" means exactly one owner at a time. If you could copy a unique_ptr, two of them would both try to delete the same object: a double free. So copying is deleted: it's a compile error. What you can do is move it, which hands ownership over and leaves the source empty (nullptr, C++'s type-safe version of C's NULL).

#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include <vector>

struct Song {
    std::string title;
    int seconds;
};

int main() {
    auto a = std::make_unique<Song>(Song{"Intro", 95});
    // auto b = a;                  // error: use of deleted copy constructor
    auto b = std::move(a);          // ownership moves to b
    std::cout << (a ? "a owns it" : "a is empty") << ", b has " << b->title << "\n";

    std::vector<std::unique_ptr<Song>> playlist;
    playlist.push_back(std::move(b));
    playlist.push_back(std::make_unique<Song>(Song{"Outro", 130}));   // a temporary moves in by itself

    int total = 0;
    for (const auto& s : playlist) total += s->seconds;
    std::cout << playlist.size() << " songs, " << total << " seconds\n";
}
a is empty, b has Intro
2 songs, 225 seconds

How it works

Taking ownership in a function

A parameter of type std::unique_ptr<T> (by value) means "this function takes ownership". The caller must write std::move(ptr), which makes the hand-over visible in the code. Inside the function, move it again to store it: items_.push_back(std::move(item));.

Your turn: complete Inventory::add, which takes ownership of an item and stores it in the vector. Then count() and total_value().

Previous: unique_ptr Next: Returning ownership