Проверить, был ли удален объект - PullRequest
4 голосов
/ 03 мая 2010

Посмотрите, пожалуйста, следующий код:

class Node
{
private:
    double x, y;
public:
    Node (double xx, double yy): x(xx), y(yy){}
};

int main()
{
  Node *n1 = new Node(1,1);
  Node *n2 = n1;

  delete n2; 
  n2 = NULL;

  if (n1 != NULL) //Bad test
  {
     delete n1;   //throw an exception
  }
}

Есть два указателя n1, n2, указывающих на один и тот же объект. Я хотел бы определить, был ли удален n2, используя тест указателя n1. Но этот тест приводит к исключению.

Есть ли способ, как определить, был ли объект удален (или не был удален), используя указатель n1?

Ответы [ 3 ]

11 голосов
/ 03 мая 2010

Насколько я знаю, типичным способом решения этой ситуации является использование указателей с подсчетом ссылок, как это делает (например) COM. В Boost есть класс шаблона shared_ptr, который может помочь (http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/shared_ptr.htm).

4 голосов
/ 03 мая 2010

Нет. Ничто в вашем коде не имеет способа достичь указатель n1 и изменить его, когда уничтожен указанный объект.

Чтобы это работало, Node должен (например) вести список всех указателей на него, и вам придется вручную регистрировать (т.е. вызывать метод) каждый раз, когда вы копируете значение указателя. Было бы очень больно работать.

0 голосов
/ 03 мая 2010

Когда у вас есть объект, он будет находиться в каком-то месте в памяти. Это значение для n1 и n2. Когда вы удаляете объект, освобождая память, которую использовал этот объект, память становится недействительной. Таким образом, вы никогда не сможете получить доступ к чему-либо, на что указывает n1, если оно было удалено.

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

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

...