在c ++中通过引用传递对象

时间:2010-10-07 00:18:28

标签: c++ linked-list pass-by-reference

这是一个noobie问题,但我不确定如何通过C ++中的引用传递。我有以下类来设置节点和一些函数。

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;
    }
};

现在,我的小课程的目的是创建一个单一链接列表,并有能力扭转它。如果我在反向结束时返回名为“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实际上并不会指向'previous'。

输出将是:

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

我真的不明白输出。有人在乎解释发生了什么吗? (为什么列表没有反转,即使我做了类似这样的root = root-> reverse(root),其中反向返回上一个,它会)为什么root现在只指向它自己?我是c ++的新手并感谢你的帮助!

3 个答案:

答案 0 :(得分:3)

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,因此应该检查。

然而,引用可能引用NULL指针,但是,如果程序员决定是邪恶的并且滥用引用语义,但原则仍然存在。

答案 1 :(得分:3)

您没有通过引用传递。您正在传递指针的副本。此副本仍指向同一节点,但它仍然只是具有本地范围的副本。基本上它是另一个指向节点的指针,指针在main中指向(ha!)。在函数结束时,您的赋值是将previous赋值给此指针副本,然后函数结束并且副本超出范围。你在main中的指针保持不变。

返回/指定指针的工作原理是返回已设置为所需内容的副本并将其分配给main中的指针。

您可以通过多种方式解决此问题。传递对指针的引用(丑陋的imo),使用引用,或者返回root并进行赋值。

答案 2 :(得分:2)

要通过引用传递指针,您可以将reverse声明为:

void reverse(Node*& root) {
  // ...
}