*星期二, 08. 五月 2018 09:10上午
*
引用
引用就是别名.
int &rnum=num;.//rnum就是num的别名,对rnum的操作就是对numde 操作
引用就是别名常量,别名是外号,属于谁就是谁的,不可更改;别名的值是数据,数据是可以修改的.
引用对象
Human Mike;
Human &rMike=Mike;//定义对象Mike的别名rMike
但我们不能定义一个类的别名,因为类Human是一个类型,他没有具体的内存地址.
Human &rHuman=Human;//错误
int a;
int &ra;
ra=a;//错误
引用就如同常量,只能对其初始化,不能赋值.
**空引用:**指针进行删除操作后,需要将他们赋为空,引用却不需要这么做,这是因为引用是原来对象的别名
###函数的参数传递
#####按值传递:之前学习的函数传参凡是都是按值传递.
int a=3,b=4;
swap(int a,int b)//swap函数交换的是a,b的副本对象的值,当传递a和b的值给函数swap时,编译器会自动在栈中创建该对象的副本对象.
cout<<"主程序中,交换后,a:"<<a<<"b"<<b<<endl;//在这行输出a,b时,a和b的副本对象已经不在栈中,他们已经被释放,所以输出的是main函数中未进行交换的值.
按址传递:把地址作为参量传递给函数.
void swap(int *pa,int *pb);//swap函数声明.*代表是指针,保存两个地址
{
int c;
c=*pa;
*pa=*pb;
*pb=c;
}
int main()
{
int a=3,b=4;
swap(&a,&b);//传递a和b的地址
}
拷贝构造函数 类X的拷贝构造函数的形式为X(X& x)。
当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:
一个对象以值传递的方式传入函数体
一个对象以值传递的方式从函数返回
一个对象需要通过另外一个对象进行初始化。
如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。
按别名传递:指针作为函数的接收参数不易阅读,出错率高,常用别名这种直接引用方式.别名即自身,更加易懂方便
void swap(int &ra,int &rb);//允许接收2个int 型变量,并用ra和rb分别作为他们的别名.接收两个别名,引用运算符 .别名即自身,对参数a b的操作就是main中a ,b.
{
int c;
c=ra;
ra=rb;
rb=c;
}
int main()
{
int a=3,b=4;
swap(a,b);//不用将ab地址传入,将a b传入即可.调用函数,并将a和b传递到函数中去,程序跳转到swap函数,将函数的2个参数ra和rb接收并初始化为a和b的别名.同时由于引用和被引用两者之间只是名字不同,内存地址相同,我们可以直接通过引用访问被引用的数据,所以不用在复制a和b的数据到栈中.
}
指针是间接访问,引用是直接访问,它是某个对象的别名,因此不用任何符号就可以直接读取该对象的数据.
利用指針返回多值
int main()
{
....
func(a,&b,&c); //返回的a被抛弃了
}
int func(int a,int *b,int *c)
{
a=a+1;
*b=
*c=
return a;
}
返回多个值并将其中一个作为判断值
int main()
{
....
check=func(a,&b,&c); //保存到check中
}
int func(int a,int *b,int *c)
{
a=a+1;
*b=
*c=
return a;
}
利用别名返回多个值
int main()
{
check=func(a,b,c); //返回的a被抛弃了
}
int func(int a,int &b,int &c)
{
a=a+1;
*b=
*c=
return a;
}