引用变量:引用已定义的变量的别名。
作用:用作函数形参,通过将引用变量用作形参,函数将使用原始数据而不是其副本,除指针外引用也为函数处理大型数据结构提供了一种非常方便的途径。
example,
int rats;
int & rodents = rats;
rats和rodents的值和地址都是一样的。
引用变量与指针变量的区别:
引用必须在声明时将其初始化,而指针变量可以先声明再对它赋初值。
引用更接近与const指针,必须在创建时初始化而且一旦与某个变量关联起来将一直效忠于它。
int rats = 50;
int & rodents = rats;//rats 和 rodents的值和地址都一样
int bunnies = 50;
rodents = bunnies; //这样的赋值无法改变rodents的引用,三个变量的值都变成了50,而rats和rodents的地址相同并且与bunnies的地址不同。
可以通过初始化声明来设置引用但不能通过赋值来设置。
【1】将引用用作函数参数
定义引用变量时对变量进行初始化,函数调用实参初始化形参,因此函数的引用参数被初始化为函数调用时传递的实参
double cube(double a) double cube(double & ra)
{ {
a *= a*a;
return a;
}
a *= a*a;
return a;
}
27 of 3 27 of 27
如果程序员的意图是让函数使用传递给他的信息而不对信息进行修改同时又想使用引用,则应使用常量引用。
double cube(const double & ra);
当数据比较大(结构和类),传递引用参数很有用。如果函数调用的参数不是左值或者与相应的const引用参数的类型不匹配,则C++标准创建类型正确的匿名变量,将函数调用的参数的值传递给该匿名变量,并让参数来引用该变量。
应尽可能使用const
1.使用const可以避免无意中修改数据的编程错误。
2.使用const是函数能够处理const实参和非const实参,否则只能接受非const实参。
3.使用const引用使函数能够正确生成并使用临时变量。
尽可能将引用形参声明为const
将引用用于结构
引用主要是为了向函数传递类和结构。
返回引用:dup = accumulate(team,five);
计算return后面的表达式并将结果返回给调用函数,这个值被复制到一个临时位置,而调用函数将使用这个值。
double m = sqrt(16.0);4.0被复制到一个临时位置然后复制给m。
accumulate()返回一个结构,而不是指向结构的引用,将把整个结构复制到一个临时位置然后再将该值拷贝到dup,但是在返回引用时,将直接吧team复制到dup,其效率更高。
返回引用应该注意的问题:
const free_throws & clone2(free_throws & ft)
{
free_throws newguy;
newguy = ft;
return newguy;
}返回一个指向临时变量的引用,也要避免返回指向临时变量的指针。
因为当函数执行完引用的临时变量就没有了,指向临时变量的函数指针可以返回但是解引用要小心、
解决办法:返回一个作为参数传递给函数的引用。
使用new分配空间并返回指向内存的地址。
返回const引用:
accumulate(dup,five) = four;//not allowed fpr const reference return
const free_throws & accumulate();
将引用用于类对象:
string version1(const string & s1, const string & s2)
{
string temp;
temp = s2 + s1 +s2;
return temp;
}
result = version1();temp被复制到一个临时存储单元中,在main中该临时存储单元内容被复制到result中。
const string & version2(string & s1, const string & s2)
{
s1 = s2 + s1 + s2;
return s1;
}
const string & version3(string & s1, const string & s2)
{
string temp;
temp = s2 + s1 + s2;
return temp;
}//致命错误,编译可以通过,但是执行时将崩溃,程序试图引用已经释放的内存。
result = version3(input, "@@@");
返回指向const对象的引用:提高效率
const Vector & Max(const Vector & v1, const Vector & v2)
{
if(v1.megval() > v2.megval())
return v1;
else
return v2;
}
返回对象将调用复制构造函数,而返回引用不会。引用指向的对象应该在调用函数执行时存在。
两个参数都是const引用,因此返回类型必须为const .
返回对象:如果被返回的对象是被调用函数的局部变量,这不应该按引用方式返回他,因为在被调用函数执行完毕时局部对象将调用析构函数,当控制权回到调用函数时引用指向的对象将不再存在。这种情况应该返回对象而不是引用,返回对象将调用复制构造函数。
何时使用引用参数:
(1)程序员能够修改调用函数中的数据对象
(2)通过传递引用而不是整个数据对象可以提高程序的而运行效率。当数据对象较大时这个原因更重要,这也是使用指针参数的原因。因为引用参数是基于指针的代码的另一个接口。什么时候使用引用?什么时候使用指针?什么时候按值传递?
如果数据对象很小,如内置的数据类型或者较小的结构可以按值传递。
如果数据对象是数组则按指针传递,这是唯一的选择,并将指针声明为指向const的指针
如果数据对象是较大的结构,则使用const指针或者const引用,以提高程序效率。可以节省复制结构所需的时间和空间。
如果数据对象是类对象,则使用const引用。传递类对象的标准方式是按引用传递。
对于修改调用函数中数据的函数:
如果数据对象是内置数据类型则使用指针。如果数据对象是数组则只能使用指针。
如果数据对象是结构则使用指针或者引用。
如果数据对象是类对象则使用引用。