Существует ли шаблон для описания того, какой объект управляет временем жизни другого человека? - PullRequest
2 голосов
/ 03 марта 2012

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

Очень простой пример:

class A
{
private:
 B *b;
public:
 A(B *_b)
 {
  if(_b)b = _b; //A should NOT destroy b
  else b = new B(); //A should destroy b
 }
}

В A::~A() вам в итоге придетсязнать.Конечно, у вас может быть небольшой логический флаг, но мне интересно, есть ли здесь какой-нибудь хорошо используемый шаблон?Или даже название этого поведения, которое я могу добавить в комментарии к коду, чтобы другой разработчик имел больше подсказок?

Ответы [ 4 ]

4 голосов
/ 03 марта 2012

Общая идея называется «Smart Pointer», в вашем конкретном примере вам нужен shared_ptr.

class A {
  std::shared_ptr<B> b;
public:
  A(std::shared_ptr<B> b = std::make_shared<B>())
    : b(b) {}
};

Обратите внимание, что вы должны использовать boost :: shared_ptr, если std :: shared_ptr недоступенна вашем компиляторе.

2 голосов
/ 03 марта 2012

В идеальном случае вы должны обрабатывать все динамические объекты с помощью интеллектуальных указателей с семантикой самоописания (и передавать ссылки для доступа или что-то вроде boost::optional для необязательных ссылок).

Ваш пример может выглядеть так:

class A
{
    std::unique_ptr<B> bptr;
public:
    A(std::unique_ptr<B> && b) : bptr(b ? b : new B) { }

    B       & b()       { return *bptr; }
    B const & b() const { return *bptr; }
};
1 голос
/ 03 марта 2012

Вы можете справиться с этим двумя указателями, одним умным, другим тупым:

class A
{
private:
    B *b;
    std::unique_ptr<B> ub; 
public:
    A(B *_b)
    {
        if(_b)
            b = _b;
        else
        {
            ub.reset(new B);
            b = ub.get();
        }
    }
};

Внутри класса вы будете иметь дело с объектом через тупой указатель, но unique_ptr будет отвечать за его время жизниесли был передан нулевой указатель.

1 голос
/ 03 марта 2012

Обычным примером является использование shared_ptr для обозначения совместного владения и std::unique_ptr или даже клеветнического std::auto_ptr для передачи передачи права собственности .

Если конструктор для A занял shared_ptr<B>, то деструктор A удалит объект, только если больше нет общих указателей.

С другой стороны, конструктор для A взял auto_ptr<B>, тогда код, составляющий A, больше не будет иметь доступа к указателю B.Таким образом, ясно, что A теперь несет единоличную ответственность за его уничтожение.

В обоих случаях право собственности обеспечивается самим кодом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...