最近重新拾起c++,复习基础知识,先对引用(&)的用法进行整理。
引用好比是对原来的变量起了一个“别名”,如int i; int &a = i;a和i对应的是相同的内存,修改a就等于修改i,类似c语言中指针的用法。
使用引用的规则:
1.引用被创建时,必须被初始化(如上例 要赋值)
2.一旦一个引用被初始化指向一个对象,它就不能改变为另一个对象的引用。(这和指针不同,指针可以指向不同的对象)
3.不可能有NULL的引用,即必须确保引用和一个合法的存储单元关联。
(《Thinking in C++:Volume One》)
下面是引用在函数传值和返回值中的用法:
#include<iostream>
using namespace std;
class TClass
{
public:
int value;
public:
TClass(const TClass &t)
{
cout<<"copy\n";
}
TClass()
{
value = 0;
}
~TClass()
{
cout<<"end\n";
}
TClass &fun(TClass &x)
{
x.value = 7;
return x;
}
};
/*
函数返回时,会把要返回的变量赋值给一个临时变量(寄存器),而后在函数外面就用该临时变量进行赋值,完成后临时变量销毁。先对下面两种用法进行说明。
*/
/*
这个函数返回一个类对象,在return x时,x将会赋值给一个临时变量,由于是对象,则会调用改类的拷贝构造函数。
*/
TClass fun2(TClass &x)
{
x.value = 9;
return x;
}
/*
*而这个函数与前一个函数不同在于函数返回引用(&),这样其实就是临时变量引用x,这样就不会在这个函数中就不会调用拷贝构造函数,
* */
TClass &fun3(TClass &x) //返回引用要和返回指针的用法一样,被返回的东西是要在外面存在的,如果返回对象引用的话,从汇编代码看,会调用拷贝构造函数。
{
x.value = 10;
return x;
}
TClass &fun4() //这样对局部变量进行引用是有问题的,当函数调用返回时,局部变量是被销毁的,局部变量的内存就收回,引用这段内存就没意义了。
{
TClass t;
t.value = 3;
return t;
}
TClass &fun5(TClass x) //x是形参,和局部变量效果一样同fun4
{
x.value = 11;
return x;
}
int main()
{
TClass T1;
TClass T2;
TClass T3;
T1 = T2; //没有用到构造函数,直接位拷贝,如C语言中结构的赋值
T1.value = 2;
T2.value = 4;
T1.fun(T2);
TClass T6 = fun2(T1); //fun2中调用拷贝构造函数,而函数返回时,没有调用,好像是直接把临时变量直接位拷贝给T6
TClass T5 = fun3(T1); //fun3中没有调用拷贝构造函数,汇编中看到,函数返回时,对T5调用拷贝构造函数(因为T5还没有创建对象要调用合适的构造函数,这里就调用了拷贝构造函数)
T2 = fun3(T1); //这样用赋值的话,没有调用拷贝构造函数,是直接位拷贝
TClass T8 = fun4(); //T8没有被赋值
TClass T9 = fun5(T1);
return 0;
}