Подтвердить что ты не робот

Что такое конструктор aliasing shared_ptr?

На этой странице (http://www.cplusplus.com/reference/memory/shared_ptr/), параграф 5, он гласит:

Кроме того, объекты shared_ptr могут делиться собственностью над указателем и одновременно указывать на другой объект. Эта способность известна как сглаживание (см. Конструкторы) и обычно используется для указания объектов-членов при владении объектом, к которому они принадлежат. Из-за этого shared_ptr может относиться к двум указателям:

  • Сохраненный указатель, который является указателем, на который он указывает, и тот, который он разделяет с оператором *.

  • Собственный указатель (возможно, общий), который является указателем, в котором группа собственности отвечает за удаление в какой-то момент и для которой она считается как использование.

Как правило, сохраненный указатель и принадлежащий ему указатель относятся к одному и тому же объекту, объекты , но псевдоним shared_ptr (те, что сконструированы с помощью конструктора псевдонима и их копии) могут ссылаться на разные объекты.

Затем я прочитал эту страницу (http://www.cplusplus.com/reference/memory/shared_ptr/shared_ptr/) о конструкторе псевдонимов shared_ptr. Но я все еще думаю, что это поведение "сглаживания" сбивает с толку. Почему здесь? Для чего это? В какой ситуации я хочу эту функцию?

4b9b3361

Ответ 1

Простой пример:

struct Bar { 
    // some data that we want to point to
};

struct Foo {
    Bar bar;
};

shared_ptr<Foo> f = make_shared<Foo>(some, args, here);
shared_ptr<Bar> specific_data(f, &f->bar);

// ref count of the object pointed to by f is 2
f.reset();

// the Foo still exists (ref cnt == 1)
// so our Bar pointer is still valid, and we can use it for stuff
some_func_that_takes_bar(specific_data);

Псевдоним предназначен для случаев, когда мы действительно хотим указать на Bar, но мы также не хотим, чтобы Foo удалялся из-под нас.


Как отмечает Йоханнес в комментариях, есть несколько эквивалентная языковая особенность:

Bar const& specific_data = Foo(...).bar;
Bar&& also_specific_data = Foo(...).bar;

Мы берем ссылку на член временного объекта, но временный Foo сохраняется до тех пор, пока specific_data. Как и в примере с shared_ptr, у нас есть Bar, время жизни которого связано с Foo - Foo которому мы не можем получить доступ.