Как я могу создать std :: shared_ptr, который имеет локальность со своим блоком управления, но является агрегатом другого класса? - PullRequest
0 голосов
/ 18 июня 2019

std::make_shared создает в куче пару блок управления / объект, для которой требуется только одно выделение, и удерживая блок управления и объект в непосредственной близости, чтобы помочь локальности.

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

* 1006 Е.Г. *

struct Bar {};
struct Foo
{
  // This would allocate the control block and object Bar on
  // the heap, which is pointed at by Foo.
  std::shared_ptr<Bar> x;

  // Example that would allocate the control block and object Bar as
  // an aggregate part of Foo. local_shared_ptr is not an actual thing
  // in the stl that I can find.
  std::local_shared_ptr<Bar> y;
}

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Я хочу, чтобы охватывающий класс управлял временем жизни, но мне нужна семантика слабых указателей.Возможно?

Ни один из них невозможен.

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

Второй не работает, поскольку семантика слабых указателей наих ядро ​​основано на том факте, что время жизни блока управления может превышать время жизни объекта, которым управляет блок управления.Если временем жизни обоих объектов управляет какой-то содержащий объект Foo, то когда Foo уничтожается, оба уничтожаются.Таким образом, срок службы блока управления заканчивается до того, как все слабые указатели будут уничтожены.

Так что нет, это не работает.

Теперь да, есть способы заставить работать такой слабый указатель,но эти способы ... неприятны.Требуется наличие связанного списка всех таких объектов со слабым указателем и обнуление их при разрушении блока управления.Но безопасность потоков становится либо невозможной (представьте себе, что такой слабый указатель копируется во время разрушения блока управления), либо требует тяжелой блокировки мьютекса для базовых операций копирования.

В целом, то, что вам нужно, это просто не то, что std::shared_ptr для.То, что вы ищете, это навязчивый указатель.И есть причина, по которой большинство предложений навязчивых указателей не имеют слабой семантики.

0 голосов
/ 18 июня 2019

Псевдоним конструктора может помочь:

struct Bar {};
struct Foo
{
    std::shared_ptr<Bar> x;
    Bar y;
};

auto foo = std::make_shared<Foo>();
foo->x = std::make_shared<Bar>();
std::shared_ptr<Bar> py{foo, &foo.y}; // use control block of foo
...