对C++中引用的增补说明(实例)
副标题#e#
#include <iostream>
#include <string>
using namespace std;
void main(int argc,char* argv[])
{
int a=10;
int b=20;
int &rn=a;
cout<<rn<<"|"<<a<<endl;
cout<<&rn<<"|"<<&a<<endl;//c++中是无法取得应用的内存地点的,取引用的地点就是取方针的地点!
rn=b;//把引用指向另一个方针----变量b
cout<<&rn<<"|"<<&a<<"|"<<&b<<endl;
rn=100;//试图改变b的值
cout<<a<<"|"<<b<<endl;//输出修改后的功效
cin.get();
}
由于引用自己就是方针的一个体名,引用自己的地点是一个没有意义的值,所以在c++中是无法取得引用的内存地点的。取引用的地点就是取方针的地点,c++自己就基础不提供获取引用内存地点的要领。
引用一单初始化,就不在可以或许被指向其它的方针,固然编译不会堕落,但操纵是不起浸染的,实际上照旧指向最先指向的方针。
上面代码中的rn=b实际在计较机看来就是a=b,所以修改的照旧a的值。
#include <iostream>
#include <string>
using namespace std;
void main(int argc,char* argv[])
{
int a=10;
void &rn=a;// 错误的,void即无范例的范例
int a[100];
int &ra[100]=a;//错误,不能声明引用数组
cin.get();
}
上面的两错误要记着引用的特性,void修饰是不可以或许声明引用的,引用是不可以或许声明数组的,即不可以或许声明引用数组。
#p#副标题#e#
下面我们要说一下,也是增补中最重要最需要把握的内容,也是对传统函数操纵的内存状态的一个增补进修。
下面我们来看一个例子:
#include <iostream>
#include <string>
using namespace std;
float c;
float test(float,float);
void main(int argc,char* argv[])
{
float pn=test(3.0f,1.2f);
cout<<pn;
cin.get();
}
float test(float a,float b)
{
c=a*b;
return c;
}
在上面的代码中我们大概我们大概觉得函数返回的就是c变量,呵呵。这么想大概就错了,普通环境下我们在函数内举办普通值返回的时候在内存栈空间内其实是自动发生了一个姑且变量temp,它是返回值的一个副本一个copy,函数在return的时候其实是return的这个姑且发生的副本。
数据在内存中的环境如下图:
上图明晰暗示了副本事事变量的环境。
下面我们再来看一种环境,就是把返回值赋给引用:
#include <iostream>
#include <string>
using namespace std;
float c;
float test(float,float);
void main(int argc,char* argv[])
{
float &pn=test(3.0f,1.2f);//告诫:返回的将是姑且变量,pn引用将成为姑且变量的别名!
cout<<pn;
cin.get();
}
float test(float a,float b)
{
c=a*b;
return c;
}
float &pn=test(3.0f,1.2f);这句在bc中可以或许编译通过,因为bc扩展配置为姑且变量配置引用,那么姑且变量的生命周期将和引用的生命周期一致,但在vc中却不能通过编译,因为一但test()执行事后姑且变量消失在栈空间内,这时候pn将成为一个没有明晰方针的引用,严重的时候会导致内存堕落。
它在内存中的环境见下图:
我们在图中看到,由于函数仍然是普通要领返回,所以仍然会有一个副本姑且变量发生,只不外,这一次只是返回一个方针地点,在main中方针地点被赋予了引用pn。
下面我们再看一种环境,这是返回引用给变量的环境:
#include <iostream>
#include <string>
using namespace std;
float c;
float& test(float,float);
void main(int argc,char* argv[])
{
float pn=test(3.0f,1.2f);
cout<<pn;
cin.get();
}
float &test(float a,float b)
{
c=a*b;
return c;
}
这种返回引用给变量的环境下,在内存中,test()地址的栈空间内并没有发生姑且变量,而是直接将全局变量c的值给了变量pn,这种方法是我们最为推荐的操纵方法,因为不发生姑且变量直接赋值的方法可以节减内存空间提高效率,措施的可读性也是较量好的。
它在内存中的环境见下图:
#p#分页标题#e#
最后的一种环境是函数返回引用,而且发值赋给一个引用的环境:
#include <iostream>
#include <string>
using namespace std;
float c;
float& test(float,float);
void main(int argc,char* argv[])
{
float &pn=test(3.0f,1.2f);
cout<<pn;
cin.get();
}
float &test(float a,float b)
{
c=a*b;
return c;
}
这种环境同样也不发生姑且变量,可读和机能都很好,但有一点容易弄错,就是当c长短main的局部变量可能是在堆内存中姑且开发厥后又被fee掉了今后的区域,这种环境和返回的指针是局部指针的效果一样严重,会导致引用指向了一个不明晰的地点,这种环境在内存中环境见下图:
由于这种环境存在浸染域的问题,故我们推荐回收第三种方法处理惩罚。
接下来我们说几个操作引用作为左值参加计较的例子,这一点一很是重要,对付领略返回引用的函数长短常有辅佐的。
#include <iostream>
#include <string>
using namespace std;
float c;
float& test(float,float);
void main(int argc,char* argv[])
{
float &pn=test(3.0f,1.2f);
cout<<pn<<endl;
test(3.0f,1.2f)=12.1;//把函数作左值举办计较!
cout<<pn;
cin.get();
}
float &test(float a,float b)
{
c=a*b;
return c;
}
凡是来说函数是不能作为左值,因为引用可以做为左值,所以返回引用的函数自然也就可以作为左值来计较了。
在上面的代码中:
float &pn=test(3.0f,1.2f);
举办到这里的时候pn已经指向到了方针c的地点了。
接下来运行了
test(3.0f,1.2f)=12.1;
把函数作左值举办计较,这里由于test是返回引用的函数,其实返回值返回的地点就是c的地点,自然c的值就被修改成了12.1。