这个问题一直很纠结,今天对此进行一些整理,主要是参考《高质量C++编程指南》和《More Effective C++》
第一层:
先从表面理解一下指针和引用之间的区别:
(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。 (2)不能有NULL 引用,引用必须与合法的存储单元关联(指针则可以是NULL)。 (3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。
摘自《高质量C++编程指南》6.6节
第二层:
“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;
但是当引用作为成员时,其占用空间与指针相同。
下面这段代码对此进行验证
//main.h class A { private: int data; std::string& rs; std::string s; public: A(int num,std::string s1):data(num),rs(s1),s(s1){}; int add(const A& a,const A& b) { int num=data+a.data+b.data; return num; } }; class B { private: std::string s; public: B(std::string s1):s(s1){}; };
#include <iostream> #include <string> #include "main.h" using namespace std; void main(void) { A a(1,"a"),b(2,"b"); A* Aptr=&a; A& Aref=a; B c("c"); B& Bref=c; cout<<"ptr="<<sizeof(Aptr)<<" reference="<<sizeof(Aref)<<" Bref="<<sizeof(Bref)<<endl; system("pause"); }
输出结果:Aptr=4,Aref=40,Bref=32(在VS2010下编译)
何时使用指针,何时使用引用:
在以下情况下你应该使用指针
1.是你考虑到存在不指向任何对象的可能。在这种情况下,你能够设置指针为空;
2.是你需要能够在不同的时刻指向不同的对象。在这种情况下,你能改变指针的指向。
在以下情况下你应该使用指针
1.如果总是指向一个对象,并且一旦指向一个对象后就不会改变指向,那么你应该使用引用。 2.还有一种情况 就是当你重载某个操作符时,你应该使用引用。
string s2("Clancy"); string& rs = s1; // rs 引用s1 string *ps = &s1; // ps 指向s1 rs = s2; // rs 仍旧引用s1, // 但是s1 的值现在是 // "Clancy" ps = &s2; // ps 现在指向s2; // s1 没有改变
摘自《More Effective C++》条款一
还需要主要一点的是对引用赋空值是很危险的,但是编译器貌似做了这种处理,因此在运行时会报错
char* pc=0; char& rc=*pc;
第三层:
为什么C++语言中既有指针也有引用?
第一,为什么有了引用还需要指针呢? 这个比较简单,因为Bjarne Stroustrup要让C++借C的势,必然要支持指针了。
第二,为什么有了指针还需要引用呢? 这个就比较复杂了,首先一开始C++是没有引用的。比如说:this,被定义为了指针,而不是引用。后来加入了引用的原因主要是为了支持operator overloading。
指针,算是一种变相的“引用”,但依然是call by value。区别在于:指针需要函数的调用者显式地来表示“引用”,比如说使用取地址符(&)把变量转换成指针。 引用,是call by reference,区别在于:引用不需要函数的调用者显式的来表示。根据所调用的函数,变量的名字可以分别解释为value或者reference。
更加深入了解参阅http://www.cnblogs.com/volatile/archive/2012/06/02/Pointer_vs_Reference_in_CPP.html
这篇博客写的非常好,下面这种情况不会编译通过
int add(const A& a,const A& b) { int num=data+a.data+b.data; return num; } int add(const A a,const A b) { int num=data+a.data+b.data; return num; }
原因当然是对重载函数调用不明确了~
第四层:
这层多少是从设计哲学来考虑,这段话说的非常好,如醍醐灌顶
实际上“引用”可以做的任何事情“指针”也都能够做,为什么还要“引用”这东西?
答案是“用适当的工具做恰如其分的工作”。 指针能够毫无约束地操作内存中的如何东西,尽管指针功能强大,但是非常危险。 就象一把刀,它可以用来砍树、裁纸、修指甲、理发等等,谁敢这样用? 如果的确只需要借用一下某个对象的“别名”,那么就用“引用”,而不要用“指针”, 以免发生意外。比如说,某人需要一份证明,本来在文件上盖上公章的印子就行了,如 果把取公章的钥匙交给他,那么他就获得了不该有的权利。
摘自《高质量C++编程指南》6.6节
总结:虽然没有自己的东西,但是总结归纳别人的知识,也从中学到了很多东西,并且确实是一件很费神的事情。
指针使用更加灵活,从某种角度来说权利也比引用大,但是权利大也会带来一些问题,引用权利小,但是适用就好,不要给过多的权限给某个操作!