通过引用传递表达式与通过引用传递变量
Passing an expression by reference vs Passing variable by reference
在下面显示的代码中,func(a3)
输入if条件并产生输出"hi"。但是,当函数的参数是表达式时,会观察到不同的行为。
例如,func(a1->right)
不会输入 if 条件。
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node *left, *right, *parent;
public:
Node(int data) : data(data) {
left = nullptr;
right = nullptr;
parent = nullptr;
}
~Node() {}
};
void func(Node*& node) {
Node* p = node->parent;
p->right = node->left;
if (node->left) {
cout << "hin";
node->left->parent = p;
}
node->parent = p->parent;
}
int main() {
Node* a1 = new Node(10);
Node* a2 = new Node(20);
Node* a3 = new Node(30);
Node* a4 = new Node(40);
Node* a5 = new Node(50);
a1->left = a2; a2->parent = a1;
a1->right = a3; a3->parent = a1;
a3->left = a4; a4->parent = a3;
a3->right = a5; a5->parent = a3;
/*
a1
/
a2 a3
/
a4 a5
*/
/* Case 1: prints hi */
func(a3);
/* Case 2: doesn't print hi */
// func(a1->right);
/* Case 3: prints hi */
// Node* ptr = a1->right;
// func(ptr);
}
我有两个问题:
当表达式的引用传递给 func 而不是变量的引用时,不同行为的原因是什么?
什么是将表达式引用传递给函数的惯用方式。
编辑:gdb输出
(gdb) b 17
Breakpoint 1 at 0x555555554856: file pointer_ref.cpp, line 17.
(gdb) r
Starting program: /home/a.out
Breakpoint 1, func (node=@0x555555767e80: 0x555555767ed0) at pointer_ref.cpp:18
18 Node* p = node->parent;
(gdb) p node->data
$1 = 30 // a3
(gdb) n
19 p->right = node->left;
(gdb) p p->data
$2 = 10 // a1
(gdb) n
20 if (node->left) {
(gdb) p p->right->data
$3 = 40 // a4
**(gdb) p node->left->data
Cannot access memory at address 0x0**
// ^^^ This seems to be the problem location
// After changing p->right to node->left,
// somehow, node->left becomes null
(gdb) p node->left
$4 = (Node *) 0x0
(gdb)
您已将引用传递给a1->right
。因此,您对该字段所做的任何更改都会显示在该函数中。p->right = node->left;
实际上将a1->right
设置为不同的节点。
在案例 3 中,您将引用传递给局部变量 ptr
,它不会更改,因为它是一个副本。
如果添加:
cout << "node was " << node << std::endl;
p->right = node->left;
cout << "node is " << node << std::endl;
您将看到您的节点发生了变化。
当表达式的引用传递给 func 而不是变量的引用时,不同行为的原因是什么?
原因就是程序中复杂的逻辑。在这种特殊情况下,当您传递a3
或a1->right
任一指针指向同一对象时,func()
本身会修改a1->right
因此,当引用传递a3
时,更改不会影响node
但当a1->right
传递时,它会影响。亨斯与众不同。
什么是没有以将表达式引用传递给函数的惯用方式。
你的方式传递引用的问题,问题是过于复杂的数据关系。例如,在您的情况下,没有理由通过引用传递此指针。
相关文章:
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 多个"常量引用"变量可以共享同一个内存吗?
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- C++方法中的引用变量
- 作为赋值(增加引用变量)C++的左操作数所需的左值
- 使用更改此变量的函数在同一行中打印引用变量
- 将延迟变量分配给引用变量
- 如何通过引用获取引用变量的地址?
- 将引用变量传递给函数
- C++中引用变量的内存?
- 按名称存储和引用变量列表
- 返回一个C++引用变量 VS 返回一个变量
- c++ 在 if 语句中分配引用变量
- 引用变量何时合适,为什么?你能解释一下实际的语法和位置吗?
- C++ - 将一个变量分配给另一个变量和将变量分配给引用变量有什么区别?
- 在类范围内声明时,应在 C++14 中引用变量模板
- 当引用变量的引用"死亡"时,它会发生什么?
- 将非按引用变量分配给返回按引用的函数,反之亦然
- 引用变量如何存储在mem中
- 引用变量存储在哪里