Собственность с физическим представлением - PullRequest
0 голосов
/ 23 ноября 2018

После прочтения RAII, просмотра презентации Херба Саттера на CppCon2014 и прочтения основных рекомендаций и связанных статей в течениеВ некоторые дни я все еще запутался в владении и связанной с ним семантике.

Допустим, класс A и класс B представляют физические объекты, и есть класс Scene и класс Process.Класс Process является функцией main, если хотите.В реальном мире A может приобрести B и физически сохранить его для себя.Это может также выпустить это.Поэтому в течение экземпляра Process объект A должен иметь возможность иметь для себя экземпляр B, а также освобождать его после того, как с ним покончено.Как и B живут в сцене, которой должен управлять процесс.

Также выводится B: A использует некоторый интерфейс, в то время как сцена использует другой интерфейс, предоставляемый B.

Давайте попробуемс некоторым кодом, по крайней мере, для Процесса:

class Process
{
public:
  void run();
};

void Process::run()
{
  auto scn = Scene {};
  auto a = A {};
  auto b = B {};

  scn.add(a);  // stores a
  scn.add(b);  // stores b

  a.acquire(b);  // stores b, and represents physical possession of a B
  a.doSomething();
  a.release(b);  // sets a's B instance to null, and physically loses the B
}

Поправьте меня здесь, если я ошибаюсь, это сомнительная часть.

Из того, что я понимаю, А должен (а не каккод) находиться в куче и указывать на shared_ptr, поскольку у Process и Scene есть свой экземпляр A. То же самое будет и для B, который хранится как в a, так и в scn, икоторый находится в процессе .Почему бы тогда scn не быть make_unique d?

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

1 Ответ

0 голосов
/ 23 ноября 2018

Владение C ++ по сути сводится к тому, «кто несет ответственность за удаление этого конкретного объекта, если они умрут в этот конкретный момент».В вашем примере, поскольку все объекты имеют автоматическое время жизни, все они принадлежат самой Process::run.В любом из add, acquire или release.

не происходит передачи права собственности. А как же обстоят дела с объектами с динамическим временем жизни?Ваше описание (где я предполагаю C вы имеете в виду Scene) может быть реализовано двумя различными способами:

  • Scene содержит std::unique_ptr с A, то естьданные
  • Scene и A могут содержать либо std::unique_ptr с или std::shared_ptr с до B.

Выбор ввторая пуля может быть сделана через определение владение , которое я изложил выше.Что происходит, когда A умирает, удерживая B?

  • Если B тоже умрет, то A является его единственным владельцем и должен удерживать его через std::unique_ptr
  • Если B должен оставаться внутри Scene, тогда Scene и A оба являются владельцами, и оба должны удерживать B через std::shared_ptr

Это не включает не владеющие (необработанные) указатели, которые могут быть полезны (например, если A владеет B, но Scene все еще нуждается в прямой ссылке для любых целей).Они должны обновляться отдельно.

...