C++ 引用和指针的区别

本文主要介绍了C++中指针和引用的联系与区别。指针指向内存地址,引用是变量别名,引用可转为指针。二者在初始化、函数参数传递等方面存在不同。还给出了作为函数参数、返回动态内存等例子,以及使用引用的陷阱和操作符返回值选择。

联系  :

     指针是指向一块内存地址的变量,这个变量可以指向其他地址;引用是一个变量的别名,只能是一个变量的别名。一个变量的引用可以转为指向它的指针。

不同:

   1.初始化不同,引用使用时必须初始化,且只能指向一个变量,初始化不能指向其他变量;指针不一样,指针使用时不必初始化,可以指向nullptr,初始化后仍可以改变指向的地址。

  2.作为函数参数传递时,引用不需要内存拷贝,所以也就不需要申请内存,因此当函数参数传递时,很多时候使用&或者const&传递参数节省内存。

 3.作为函数参数传递时,如果想改变传递进函数参数的原始变量的值,引用改变后改变原始变量,而指针的值改变后并不会改变原始变量,因为它只是一份内存副本,如果想达到改变的效果,使用**。

4.引用的++ 是变量本事的运算,而指针的++,是内存地址的++。

5.如果返回动态内存分配的对象或者内存,必须使用指针,引用可能引起内存泄漏。

6.不要返回局部变量引用,返回对象的引用最好const变量。

7.操作符<< 和 >> =返回引用,而操作符+-/*的返回对象不能是引用。

例子。

例子1,作为函数参数时,三种函数实现改变外部变量

void swap1(float *a, float *b)
{
	float temp = *a;
	*a = *b;
	*b = temp;

}
void swap2(float &a, float &b)
{
	float temp = a;
	a = b;
	b = temp;

}
void swap3(float **a, float **b)
{
	float temp = **a;
	**a = **b;
	**b = temp;
}
void main()
{
	float a = 12, b = 20;
	float *aPtr = &a, *bPtr = &b;
	std::cout << "a: " << a << "   b:" << b << endl;
	swap1(aPtr, bPtr );
	std::cout << "a: " << a << "   b:" << b << endl;
	swap1(&a, &b);
	std::cout << "a: " << a << "   b:" << b << endl;
	swap2(a, b);
	std::cout << "a: " << a << "   b:" << b << endl;
	float **aPtrPtr = &aPtr, **bPtrPtr = &bPtr;
	swap3(aPtrPtr, bPtrPtr);
	std::cout << "a: " << a << "   b:" << b << endl;
}

  

2.返回动态内存分配的对象或者内存

string& foo()
{
   string* str = new string("abc");
   return *str; 
}

 这样写的坏处是可能造成内存泄漏,如果string str = foo(),那么这个临时内存就没法释放

3.一些使用引用陷阱


void do(string & s)
{
   std::cout<<s<<endl;
}
void main()
{
  do("Test");
}

表达式非法,因为"Test"和函数返回值这些字符都是临时对象,而在C++中,这些临时对象都是const类型的,因此需要const string &做参数。

操作符问题,引用百度百科解释

      流操作符<<和>>,这两个操作符常常希望被连续使用,例如:cout << "hello" << endl; 因此这两个操作符的返回值应该是一个仍然支持这两个操作符的流引用。可选的其它方案包括:返回一个流对象和返回一个流对象指针。但是对于返回一个流对象,程序必须重新(拷贝)构造一个新的流对象,也就是说,连续的两个<<操作符实际上是针对不同对象的!这无法让人接受。对于返回一个流指针则不能连续使用<<操作符。因此,返回一个流对象引用是惟一选择。这个唯一选择很关键,它说明了引用的重要性以及无可替代性,也许这就是C++语言中引入引用这个概念的原因吧。赋值操作符=。这个操作符象流操作符一样,是可以连续使用的,例如:x = j = 10;或者(x=10)=100;赋值操作符的返回值必须是一个左值,以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。

    在另外的一些操作符中,却千万不能返回引用:+-*/ 四则运算符。它们不能返回引用,Effective C++[1]的Item23详细的讨论了这个问题。主要原因是这四个操作符没有side effect,因此,它们必须构造一个对象作为返回值,可选的方案包括:返回一个对象、返回一个局部变量的引用,返回一个new分配的对象的引用、返回一个静态对象引用。根据前面提到的引用作为返回值的三个规则,第2、3两个方案都被否决了。静态对象的引用又因为((a+b) == (c+d))会永远为true而导致错误。所以可选的只剩下返回一个对象了。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值