这是一个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 ++的新手并感谢你的帮助!
答案 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) {
// ...
}