C++引用的用法

什么是引用?

       引用就是某一变量或者某一目标的别名。对引用的操作就是对实际变量的操作。引用的声明方式:类型标识符 &引用名=目标变量名。

    (1)&在此不是求地址运算,而是起标识作用。
    (2)类型标识符是指目标变量的类型。
    (3)声明引用时,必须同时对其进行初始化。
    (4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。
       int a,&ra=a;
       a为目标原名称,ra为目标引用名。给ra赋值:ra=1; 等价于 a=1;
    (5)对引用求地址,就是对目标变量求地址。&ra与&a相等。即我们常说引用名是目标变量名的一个别名。别名一词好像是说引用不占据任何内存空间。但是编译器在一般将其实现为const指针,即指向位置不可变的指针。即引用实际上与一般指针同样占用内存。
    (6)不能建立引用的数组。因为数组是一个由若干个元素所组成的集合,所以无法建立一个由引用组成的集合。但是可以建立数组的引用.
例如: int& ref [3]= {2,3,5};//声明ref引用的数组错误
但是可以这样写:
const int (&ref)[3] ={2,3,5};
为什么要加上const ,因为{2,3,5}此时是个字面值数组,是保存在代码段里,只读的属性,如果不加,编译错误,而且后面对ref[0]的赋值也不会成功.
需要特别强调的是引用并不产生对象的副本,仅仅是对象的同义词。
     (7)引用必须在定义时马上被初始化,因为它必须是某个东西的同义词。你不能先定义一个引用后才
初始化它。例如下面语句是非法的:
Point &pt3;
pt3=pt1;
     (8) 引用是除指针外另一个可以产生多态效果的手段。
这意味着,一个基类的引用可以指向它的派生类实例。例如:

class A;
class B: public A
{
   ...
};

B b;
A & aRef = b;    // 基类引用指向派生类

如果A类中定义有虚函数,并且在B类中重写了这个虚函数,就可以通过aRef产生多态效果。

 
下面是引用的使用例子,说明都在代码注释里了。
#include <iostream>
using namespace std;
void swap1(int a,int b);
void swap2(int* a,int* b);
void swap3(int& a,int& b);
void swap4(const char* a,const char* b);
void swap5(const char** a,const char** b);
void swap6(const char*& a,const char*& b);

int main()
{
	int a = 10,b = 20;
	swap1(a,b);
	cout<<"swap1"<<" : "<<a<<" , "<<b<<endl;	//输出10,20;
	swap2(&a,&b);
	cout<<"swap2"<<" : "<<a<<" , "<<b<<endl;	//20,10
	swap3(a,b);
	cout<<"swap3"<<" : "<<a<<" , "<<b<<endl;	//10,20 因为swap2已经交换了;

	const char* pa = "hello";
	const char* pb = "world";
	swap4(pa,pb);
	cout<<"swap4"<<" : "<<pa<<" , "<<pb<<endl;	//hello,world;
	swap5(&pa,&pb);
	cout<<"swap5"<<" : "<<pa<<" , "<<pb<<endl;	//world,hello;
	swap6(pa,pb);
	cout<<"swap6"<<" : "<<pa<<" , "<<pb<<endl;	//world,hello;

	system("pause");
	return 0;
}

//值传递,只是形参的交换,并没有实现实参的交换;
void swap1(int a,int b)
{
	int c = a;
	a = b;
	b = c;
}

//形参指向的是实参的地址,直接对实参地址内容的交换就是实参值的交换;
void swap2(int* a,int* b)
{
	int c = *a;
	*a = *b;
	*b = c;
}

//引用交换,形参引用就是实参的别名,引用实质是指针,看上去交换的是形参的值,实际上交换的就是实参;
void swap3(int& a,int& b)
{
	int c = a;
	a = b;
	b = c;
}

//因为实参本身就是指针,所以仍然是值传递,并没有对实参的地址交换;
void swap4(const char* a,const char* b)
{
	const char* c = a;
	a = b;
	b = c;
}

//传递实参的地址,完成实参值的交换;
void swap5(const char** a,const char** b)
{
	const char* c = *a;
	*a = *b;
	*b = c;
}

//使用指针的引用,实际上交换的就是实参;
void swap6(const char*& a,const char*& b)
{
	const char* c = a;
	a = b;
	b = c;
}

//判断指针和引用的时候,需要从右向左读 例如 char ** a 则 a 是一个指针,指向另一个指针,而另一个指针指向的是char;
//const char*& b 则 b 是一个引用,是一个指针的引用,而指针指向的是一个 const char;


//引用的作用一般是为了节约效率,例如函数传递的参数是结构体,或者类,那么如果进行值传递,性能就比较低;
//但是需要注意的是,引用一般搭配const类型一起使用。因为这样可以避免在参数传递时,由于程序员的失误导致的实参值篡改;


//另外,引用还被用于函数的输出参数;
//指针方式;
double calcircle1(double r,double* area)
{
	*area = 3.14 * r * r;	//圆的面积;
	return 2 * 3.14 * r;	//圆的周长;
}
//调用方式;
double area;
double c = calcircle1(3,&area);

//引用方式;
double calcircle2(double r,double& area)
{
	area = 3.14 * r * r;	//圆的面积;
	return 2 * 3.14 * r;	//圆的周长;
}

//调用方式;
double area;
double c = calcircle2(3,area);

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Valar Morgulish

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值