Собственность с физическим представлением

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

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

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

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

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

1 ответ

Решение

Владение 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 все еще нужна прямая ссылка для любой цели). Они должны быть обновлены отдельно.

Другие вопросы по тегам