Передача объекта по ссылке в c ++ - PullRequest
0 голосов
/ 07 октября 2010

Это вопрос новичка, но я не уверен, как передать по ссылке в C ++.У меня есть следующий класс, который устанавливает Node и несколько функций.

class Node
{
  public:
    Node *next;
    int data;
    Node(int dat)
    {
      next = NULL;
      data = dat;
    }
    Node* getNext()
    { return next; }
    void setNext(Node *n)
    { next = n;}

    void reverse(Node *root)
    {
      Node *previous = NULL;
      while(root != NULL)
      {
        Node *next = root->getNext();
        root->setNext(previous);
        previous = root;
        root = next;
      }
      root = previous;
    }
};

Теперь цель моего маленького класса - создать единственно связанный список и иметь возможность его реверсировать.И, кажется, работает нормально, если я возвращаю узел с именем «предыдущий» в конце реверса.

Но посмотрите на мою основную функцию:

int main()
{
  Node *root = new Node(1);
  Node *num2 = new Node(2);
  Node *num3 = new Node(3);
  Node *num4 = new Node(4);

  root->setNext(num2);
  num2->setNext(num3);
  num3->setNext(num4);
  root->printList();
  root->reverse(root);
  root->printList();

  return 0;
}

printList () был опущен дляради места, но он просто печатает список с данным узлом.Проблема в том, что когда вызывается root-> reverse (root), root фактически не указывает на «предыдущий».

Вывод будет следующим:

1
2
3
4
  // the value of previous from the reverse function is 4
1

Iдействительно не понимаю выход.Кто-нибудь хочет объяснить, что происходит?(Почему список не переворачивается, даже если я сделал что-то вроде этого root = root-> reverse (root), где reverse возвращает предыдущий, так и будет) Почему этот root теперь указывает только на себя?Я новичок в C ++ и ценю вашу помощь!

Ответы [ 3 ]

3 голосов
/ 07 октября 2010

Вы не передаете по ссылке.Вы передаете копию указателя.Эта копия все еще указывает на тот же узел, но это все еще просто копия с локальной областью действия.По сути, это еще один указатель, указывающий на узел, на который указывает указатель в main (ха!).В конце вашей функции ваше назначение назначает previous этой копии указателя, и затем функция завершается, и копия выходит из области видимости.Ваш указатель в main остается неизменным.

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

3 голосов
/ 07 октября 2010

C ++ имеет поддержку семантики ссылок. Поэтому для заданной функции:

void foo(Bar& bar);

Для перехода по ссылке вы делаете:

int main() {
  Bar whatsit;

  foo(whatsit);

  return 0;
}

Вот и все!

Обычно это путают с передачей указателя, где для такой функции, как:

void foo(Bar* bar);

Вы бы сделали:

int main() {
  Bar whatisit;

  foo(&whatsit);

  return 0;
}

Разница в основном связана с семантикой: - Ссылка всегда действительна. Нет причин проверять NULL-указатель. - Указатель может быть НЕДЕЙСТВИТЕЛЕН, и поэтому должен быть проверен.

Однако для ссылки возможно сослаться на указатель NULL, однако, если программист решает быть злым и злоупотреблять семантикой ссылок, но принцип остается.

2 голосов
/ 07 октября 2010

Чтобы передать указатель по ссылке, вы можете объявить reverse как:

void reverse(Node*& root) {
  // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...