Можно ли в вектор отправлять объект по ссылке?

Я ранее активно использовал C#, но понадобилось создать приложение на C++. И я не пойму, почему вектор не реагирует на изменения элементов.

Приведу пример из C#:

class Program
{
    static void Main(string[] args)
    {
        List<Book> books = new List<Book>();
        Book book1 = new Book();
        books.Add(book1);

        book1.id = 5; // на это изменение реагирует список *books*. То есть его элемент тоже теперь имеет id = 5
    }
}

class Book
{
    public int id = 1;
}

В данном случае элемент списка и объект ссылаются на один адрес, но у меня не получается сделать то же самое в C++

class Book
{
public:
    int id = 1;
};


int main()
{
    vector<Book> books;
    Book book1 = Book();

    books.push_back(book1);

    book1.id = 5;

    cout << &book1 << " " << &books[0] << endl;

    return 0;
}

Но справедливо заметил, что элемент вектора и book1 ссылаются на разные адреса. И я не пойму, почему там разные адреса, хотя в объявлении функции push_back() у вектора сказано, что объект получает ссылку, а не копию.

Если это невозможно в принципе, то нет ли обходного пути, чтоб напрямую не обращаться к элементу вектора?


Ответы (1 шт):

Автор решения: αλεχολυτ

В C++ контейнеры хранят объекты по значению. Для достижения поведения схожего с C#, достаточно использовать контейнер указателей, но чтобы не было заморочек с владением и временем жизни объектов, на которые эти указатели будут указывать, должны быть не обычные сырые сишные указатели, а их "умные" компаньоны. В данном случае вам проще всего подойдёт std::shared_ptr.

std::vector<std::shared_ptr<Book>> books;
auto book1 = std::make_shared<Book>();

books.push_back(book1);

book1->id = 5;

std::cout << book1.get() << " " << books[0].get() << '\n';
→ Ссылка