C++中的引用

首先回顾一下C语言中的两种传递方式:
值传递和地址传递

优点缺点
值传递语法简洁、操作简单需要值拷贝,如果对象较大,开销也大,不能直接操作外部变量。
地址传递语法较为复杂操作过程中容易遗漏取地址符号、或者解引用符号,但是传递时候只传递指针大小,效率较高,也能够直接操作数据。
//值传递
void ModifyValue(int a)
{
    // 函数内部不能修改外部的值
}

//地址传递
void ModifyValue(int *a)
{
    //  修改外部值的时需要解引用
    *a = 20;
}

void test()
{
    int num = 10;
    ModifyValue(num);
    ModifyValue(&num);
}

C++中的引用

引用是 C++ 对 C 的重要扩充。在 C/C++ 中指针的作用基本都是一样的,但是 C++ 增加了另外一种给函数传递地址的途径,这就是按引用传递(pass-by-reference),它也存在于其他一些编程语言中,并不是 C++ 的发明。

引用的语法

Type &ref = val;

引用规则:

  • &在此不是求地址运算,而是起标识作用。
  • 类型标识符是指目标变量的类型
  • 必须在声明引用变量时进行初始化,初始化之后不能改变。
  • 不能有 NULL 引用。必须确保引用是和一块合法的存储单元关联。
//1 . 引用语法
void test()
{
  	//引用一旦产生就必须马上初始化(关联合法对象)
 		int &ref1; 	//err  
		//引用不能指向NULL	(有合法内存的可以放在=左边,没有合法内存的放在=右边)
    int &ref2 = NULL; // err



    // 类型标识符是指目标变量的类型
    int v = 10;
  	//也就是说引用其实就是已有对象的别名
    int &vr = v;
    
   
    int b = 20;
    vr = b;  // 并非修改 vr 引用

    // 可以对引用再建立引用, or vr v 地址一样
    int &or = vr;
}

自定义类型引用

class Person
{
	public:
			string name;
			int age;		
}


void test()
{
		Person p = {"wuyou",18};
		Person &pRef = p;
		cout<<(int)&p<<endl;
		cout<<(int)&pRef<<endl;
}

对数组的引用

int array[] = {1,2,3,4};

int(&p)[4] = array;

//打印变量的类型
cout<<typeid(p).name()<<endl;	

指针引用

  • 在C语言中,我们如果要在函数内部修改外部变量,必须传递指针
  • 引用所占空间大小与指针大小相同,只是这个过程由编译器内部实现,对用户不可见

语法:
& 左侧 变量类型
& 右侧 变量名

struct Person
{
	public:
			string name;
			int age;		
}

//C语法
int CreatePersonC(Person **p)
{
	//判断参数...
	
	//注意不能隐式类型转换
	Person *p2 = (Person*)malloc(Person));
	//判断申请的空间...
	
	p2->age = 20;
	*p = p2;
}

//C++语法
int CreatePersonCpp(Person* &p)
{
	p = (Person*)malloc(Person));
	//判断申请的空间...
	
	p->age = 20;

}

void FreeCreatePersonCpp(Person* &p)
{
	free(p);
	p = NULL;
}
void test()
{
	Person	*p = NULL;
	CreatePerson(&p);
	CreatePersonCpp(p);
	cout<<((p == NULL) ? "空":"非空")<<endl;
}

常量引用(万能引用)

作用:

  • 避免函数内部修改外部数据。
  • 可以对字面量进行引用。
  • const
    示例
//使用const修饰之后,内部不不能修改value的值
void printFunc(const int &value)
{
	cout <<value<<endl;
}

void test()
{
	//首先看看字面量的引用
	int ref = 10;
	int &ref1 = reg;
	
	int &ref2 = 10; //err 原因是字面量没有内存

	//万能引用,任何类型都可以引用
	const int &ref3 = 10; 
	

}

引用的机制

引用的本质就是通过指针来实现的
C++中的引用简化了指针的操作(取地址,解引用)

void test()
{
	int a = 10;
	int &ref = a;  // int *const ref = &a;
	ref = 100; 	//*ref = 100;

}

引用注意点

  • 引用不产生新的变量(就是一个别名),减少形参与实参传递时的开销;
  • 由于引用可能导致实参随形参改变而改变,将其定义为常量引用可以消除这种副作用;
  • 不存在空值的引用,意味着我们在使用引用的时候不需要判断是否为 NULL,一定程度上提升了效率;
  • 引用传递的性质像是指针传递,但是书写方式像值传递,引用的语法要比指针的语法更加易读和操作,指针能做的事情,引用也能做.
  • 最常见看见引用的地方是在函数参数和返回值中。如果从函数中返回一个引用,必须像从函数中返回一个指针一样对待。当函数返回值时,引用关联的内存一定要存在。
int &my_func()
{
    int a = 10; //不要返回局部变量  err   原因,函数调用结束,函数函数从内存中销毁
	 static int a = 10;
    return a;
}

void test()
{
	//函数的返回值,如果是引用接,那就是别名
	//函数的返回值,如果是值,那就值拷贝
    int &result = my_func();

	int ret = my_func();
	cout <<(int)&result <<endl;
	cout <<(int)&ret<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值