Почему второй указатель на объект не имеет значение NULL, а указатель объекта? - PullRequest
0 голосов
/ 04 июля 2011
#include <iostream>

using namespace std;

class Object{};

class Connection
{
  public:
    Connection(Object * _obj);
    Object * obj;
    void status();
};

Connection::Connection(Object * _obj)
{
  obj = _obj;
}

void Connection::status()
{
  cout << obj << endl;
}


int main() {
  Object * myObj = new Object();

  Connection * myConn = new Connection(myObj);

  delete myObj;
  myObj = NULL;

  cout << myObj << endl;
  myConn->status();
  /*
  Output is:

  0
  0x25ec010

  but should be:

  0
  0

  */
}

Я думал, что в этом примере я работаю только с указателями.Поэтому я не понимаю, почему указатель в "myConn" тоже не установлен в NULL, потому что есть два указателя, которые указывают на один и тот же адрес.

Ответы [ 4 ]

1 голос
/ 04 июля 2011

Это не должно быть 0, потому что вы копируете значение указателя.Попробуйте вместо этого использовать ссылки (&).

Возможно, это не лучший пример, и boost::shared_ptr будет лучшим решением, но этот код будет работать:

 // skipped...
 class Connection
 {
 public:
   Connection(Object **_obj);
   Object **obj;
   void status();
 };

 Connection::Connection(Object **_obj) : obj(_obj) { }
 void Connection::status() { cout << *obj << endl; }

 int main()
 {
   Object * myObj = new Object();
   Connection * myConn = new Connection(&myObj);
 // skipped
1 голос
/ 04 июля 2011

*myConn сделал копию вашего myObj указателя (когда вы сказали obj = _obj;). Копия не была установлена ​​в нуль. (Но он по-прежнему указывает на недействительный адрес, поэтому не разыменовывайте его!)

0 голосов
/ 04 июля 2011

Указатель является отдельной сущностью от объекта, на который он указывает.

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

Этот факт вызывает проблему в примере кода, который вы опубликовали: после удаления объекта с помощью указателя myObj вы правильно установите указатель на NULL, чтобы указать, что он больше не указывает на действительный объект. Однако указатель myConn->obj по-прежнему указывает на уже удаленный объект (т. Е. Указатель больше не действителен).

Использование общего указателя ( boost :: shared_ptr ) может помочь в такой ситуации.

0 голосов
/ 04 июля 2011

Connection :: obj не указывает на myObj, оно указывает на значение, которое хранит myObj.Поэтому, если вы хотите исправить это, вы должны вручную установить значение null в функции.Или создайте второй указатель, который содержит указатель на объект obj, и проверьте, является ли он пустым, но не слишком ли это усложнит.

...