Unique_ptr

Hi there

good to see that website if back and running :)

I am having difficulty with my project. it is Library with books that can be borrowed by user.
there are three classes Library, user and Book.

Final version will have option for user to set size of the Library (lest say 10 spaces for books)
User will be able to list books pick 1 and borrow it.
Return book to Library and get another book.

I am having trouble with transferring my uniqute_ptr of Book type to Library class.

In main
1
2
3
  std::unique_ptr<Book> book_ptr = std::make_unique<Book>("title", "author", 1111); // I am creating object 
  std::vector<Library> lib; // I am creating lib object which is a vector of type Library
  lib.at(0).Add(book_ptr); // I am adding pointer of Book type to method add 


In Library
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Library
{
private:
    std::vector<std::unique_ptr<Book>> shelf_with_books;

public:

void Add(std::unique_ptr<Book> bk) 
    { // I have tried this 3 approaches none seems to be working (comment uncomment required lines)
        shelf_with_books.push_back(bk); //1 does not work
        shelf_with_books.push_back(std::move(bk)); // 2 does not work
        shelf_with_books.push_back(std::make_unique(bk)); // 3 does not work

    }


i am wondering what I am doing wrong?

below is my full code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <string>
#include <vector>
#include <memory>

class Book
{
private:
    std::string title;
    std::string author;
    int publication_year;
    // please add ID
public:
    Book(std::string title, std::string author, int publication_year) : title(title), author(author), publication_year(publication_year)
    {}
    void create()
    {

    }
    void const printB() {
        std::cout << "Title: " << title << '\n';
        std::cout << "Author: " << author << '\n';
        std::cout << "Publication Year: " << publication_year << '\n';
    }
};
class Library
{
private:
    std::vector<std::unique_ptr<Book>> shelf_with_books;

public:
    void Reserve_space()
    {

    }
    void Add(std::unique_ptr<Book> bk)
    {
        shelf_with_books.push_back(bk); //1 does not work
        shelf_with_books.push_back(std::move(bk)); // 2 does not work
        shelf_with_books.push_back(std::make_unique(bk)); // 3 does not work

    }
    void Borrow()
    {

    }
    void Return()
    {

    }
    void const Print()
    {
        for (auto &shelf_with_book : shelf_with_books) {
            shelf_with_book->printB();
        }
    }
};
class Person
{
private:
    std::vector<std::unique_ptr<Book>> user_books;
public:
    void Borrow()
    {

    }
    void Return()
    {

    }
    void Print()
    {

    }
};

int main() {

    std::unique_ptr<Book> book_ptr = std::make_unique<Book>("title", "author", 1111);
    

    std::vector<Library> lib;
    lib.at(0).Add(book_ptr);
You cannot copy a unique_ptr, only move it, so you need to use std::move when passing it to the Add function.

 
lib.at(0).Add(std::move(book_ptr));


Number 2 is correct inside Add.

 
shelf_with_books.push_back(std::move(bk));


lib is a vector of libraries but you have not added any libraries to it so lib.at(0) will throw an exception. If you only want to use one library in your program there is no need to use vector here.

1
2
Library lib;
lib.Add(std::move(book_ptr));
Last edited on
thanks Peter :)

that was much appreciated, I was thinking about moving it but I assumed (wrongly) it would be sufficient if I do this at the other end of function.

thank you :)

another question
Why I am unable to use push_back with lib vector?
1
2
 lib.push_back(std::move(book_ptr)); // <- does not work
//    lib.at(0).Add(std::move(book_ptr) 
Last edited on
Why are you using pointers at all? This could be done without pointers at all.

yes it can be, this is exercise with use of smart pointers (unique_ptr)
:)
xxvms wrote:
Why I am unable to use push_back with lib vector?
lib.push_back(std::move(book_ptr)); // <- does not work

If lib is still a vector of libraries it doesn't work because book_ptr is not a Library.
If you have changed lib to a Library object it doesn't work because the Library class doesn't have a function named push_back.
Last edited on
hmmm make sense.

thank you Peter it really started to clear unique_ptr in my mind now :)
Last edited on
Yes, it seems like you're on the right track except that you should not use std::move when declaring the function parameter.

1
2
3
4
void add( std::move( std::unique_ptr<Book>bk ) )
{
    shelf_with_books.push_back(std::move(bk));
}
yes found that as well :) thank you
Topic archived. No new replies allowed.