2015-06-22 2 views
2

Скажем, у меня есть класс:Детектирование если объект еще активен, или он был уничтожен

class Foo { 
public: 
    int a; 
} 

Этот класс конкретизируется через new оператора и уничтожены с помощью delete оператора на объект B класса Bar.

Если объект B класса Bar, создает новый объект A класса Foo, а затем он передает указатель объекта A объекту C класса Baz. Если объект B класса Bar был удален самостоятельно, то как может объект C класса Baz обнаружить, если объект A активен или был удален. Примечание: это очень маленькая встроенная система, поэтому никакие библиотеки не могут использоваться, даже не std. См. Диаграмму последовательности ниже.

|------|        |------| 
| B:Bar|        | C:Buz| 
|------|        |------| 
    ||   |-------|     || 
    ||---New--->| A:Foo |     || 
    ||   |-------|     || 
    ||    ||      || 
    ||    ||      || 
    ||-----C:Buz.set_foo_Ptr(&A:Foo);----->|| 
    ||    ||      || 
    ||---Delete--->X      || 
    ||          || 
    X (B:Bar Self Deleted)    || 
              || 
          (Can C:Buz know if A:Foo 
          has been deleted or not ?) 
+3

Похоже, хороший кандидат на ['std :: weak_ptr'] (http://en.cppreference.com/w/cpp/memory/weak_ptr) – CoryKramer

+0

Я не знаю, что стандарт говорит об этом использовании, но будет ли динамичная работа (и надежно)? – donjuedo

+0

Вам это нужно * не * быть удаленным? Или удаляет потенциально нормально? – Barry

ответ

4

У вас здесь проблемы с владением. Как правило, для этого нужно использовать один из умных указателей stl, но, как вы сказали, нет stl ... вам нужно будет очень тщательно и явно управлять владением указателем.

Передача указателя на A вокруг без закрывающего объекта - плохая идея. Теперь вы C владеете A, но B также владеет A. Это не хорошо. Либо передайте B в C, либо C-доступ A через B или предоставите функции доступа. Или перейдите от A до C и убедитесь, что C - единственный объект, который управляет A (т.е. C будет удалять все объекты A независимо).

Я думаю, если вам нужно, вы должны указать флаг с B, который определяет, кто имеет право собственности на A - по умолчанию он установлен в «B», но после прохождения через него может быть установлен «C» и используется когда B удаляется, чтобы сообщить B, удалить A или нет.

0

Два варианта:

  • Если вам просто нужно знать, используют std::atomic<bool> переменную, которая говорит, что если объект еще существует
  • Вместо этого, если onject C еще нужно получить доступ к объекту, используйте умные указатели.
1

Ну, по определению вы не можете, так как объект, который был уничтожен, больше не существует. И вы не можете проверить, что не существует ...

Более практичным подходом был бы уже указатель weak_ptr, или сигнал & слот-комбо для уведомления заинтересованных объектов об уничтожении A.

+0

Спасибо, это то, что я думал, но хотел получить больше информации. Я задаю следующий вопрос: http://stackoverflow.com/questions/677653/does-delete-call-the-destructor. – user1135541

+0

Итак, после того, как я задал второй вопрос, @gbjbaanb управляет мной в лучшем направлении, поэтому я собираюсь отметить его в качестве ответа, дать вам голосование, спасибо ... – user1135541

+0

Без проблем; иногда появляется лучшее решение для ваших проблем. Stackoverflow - это не оракул, хотя он очень и очень близок :) – JvO

0

Вы можете использовать деструктор B для вызова C:Buz.set_foo_Ptr(nullptr);, а затем C может проверить значение nullptr перед его использованием.

Смежные вопросы