编写二叉树时引出的对C++引用变量的思考

引用变量


二叉树传送门:http://lyxf.live/posts/336f1d3d/

1、首先我们从void creatBtree_Qian(Node<T> *&p,T t);这个递归创建二叉树的函数说起

  • 必须使用指针引用变量
    • 因为指针为初始的时候,结点中我设置的左右指向指针为NULL,递归调用到creatBtree_Qian(p->left,t);这样的函数时候,p->left为NULL如果不用引用,只是使用指针作为参数,那么传递的只是NULL这个值给了p,p是新创建的一个指针变量,然后接下来p指向结点,结点存入值后进入下一个调用,函数体结束的时候这个p就会丢失,使用引用之后,相当于真的把这个指向指针传递了过去,之后将这个指针指向新结点,是可以被“记住”的

2、其次对引用变量不为空的“纠正”理解

  • 引用变量不能是空不是引用变量不能为NULL

当在主函数调用void creatBtree_Qian()这个函数的时候,我发现,将获得头结点的函数当作参数会编译报错。 test.creatBtree_Qian(test.getRoot(),-1)不可编译

各种测试后首先个人认为原因是因为test.getRoot()函数,在当时是的把root=NULL,只是把这个NULL的值传了回去。相当于Node<int> *&t2=NULL这个是不可以的。

而先把返回值NULL存入一个相应指针变量,在将这个指针变量赋给引用指针变量是可以的

即:

1
2
Node<int> *t=test.getRoot();
Node<int> *&a=t;

这样是可以的。

所以:

1
2
Node<int> *t=test.getRoot();
test.creatBtree_Qian(t,-1)

这样就正确了。

所以引用变量非空不是不能为NULL,而是不能没有任何实际地址能够赋给他

但是将构造函数改变之后,明明返回值不是NULL了却依旧报错,-个人猜测是因为return机制下返回值被保存在寄存器中等待变量来访问获取结构,所以普通指针能够访问保存,而引用变量直接获取地址,相当于起个别名罢了,但是寄存器中的数据无法提供给引用变量地址故报错。当然待求证,毕竟只是初学者

2019.12.15:猜想错误,详见下文

3、但是问题又来了

这样root不能够直接作为根创建树,毕竟这样t只是接受了test.getRoot()返回的值而已,之后的一系列操作也都是基于t上创建二叉树,传递不到root。

所以我们干脆这样:

main函数中直接随便创建一个结点指针,传入创建函数中,最后创建完毕将这个指针赋给root:

于是我们在创建函数中添加一句:root=p

1
2
3
4
5
6
7
8
9
10
11
12
13
template <class T> 
void Btree<T>::creatBtree_Qian(Node<T> *&p,T t) //参数必须为结点指针的引用 否则无法链接起来各个结点
{
T a; //我们的操作步骤如下:
cin>>a;
if(a==t) //1、根据输入字符 判断 是否按照相应顺序存入数据
return;
p=new Node<T>; //2、若需要存入数据,我们需要创建并且链接一个结点
p->data=a; //3、之后根据我们相应的创建顺序,决定数据的存放顺序
creatBtree_Qian(p->left,t); //4、这里是前序,所以,我们存数据,对左结点继续操作
creatBtree_Qian(p->right,t); //5、确认左结点创建完毕后 对右结点操作
root=p; //6、将“真树根”传给root。
}

虽然每个创建函数结束都会调用一次root=p,但是根据递归函数的特点,在这个函数中,当跳出最后一次函数体的时候,root的值一定是会被根节点赋予,而不是分支结点

最后总结一下一个个人猜测的结论:任何函数的返回值都不能直接赋给一个引用变量

2019.12.15补充:关于树的封装,见:二叉排序树的实现和应用,同时猜测结论正确!下面是原因

引用不能绑定到临时对象!可以简单理解它相当于一个右值(例如a=2的2,他是不能被引用的)。

而解决问题,再根据二叉排序树的实现和应用中返回引用的理解,这里我们把getRoot()返回类型设为引用即可将test.creatBtree_Qian(test.getRoot(),-1)的编译正确

最基础的,但是正确的理解:左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式),右值指的则是只能出现在等号右边的变量(或表达式).其他深入理解,见下文推荐阅读:

具体了解左值右值:

c++中的左值与右值

C++左值与右值

-----------------------本文结束 感谢阅读-----------------------
坚持原创技术分享,您的支持将鼓励我继续创作!恰饭^.^~