More Effective C++(1):pointers和references

版权声明:欢迎转载,请注明出处 https://blog.csdn.net/weixin_38339025/article/details/89062756

首先,我们从pointers(指针)、reference(引用)、casts(类型转换)、arrays(数组)、constructors(构造函数)说起,这些议题,几乎是C++程序最基础的部分,大多数情况都会用到上述所有特性。

首先,今天作为此专题的第一节,我们谈一下pointers和references的区别

想必C/C++的初学者对pointers和references的感觉是既爱又恨的。他们看起来很不一样(pointers使用“*”和“->”操作符,而references则使用“.”)但是它们却似乎做着相同的事情。
第一,你必须认识到,没有所谓的null reference(空引用)。一个reference(引用)必须总代表某个对象。若有一个变量,其目的是用来指向(代表)另一个对象,但是也可能它不指向(代表)任何对象,那么则应该使用pointer(指针),因为你可以将pointer设置为null。换个角度看,若这个变量总是必须代表一个对象,即不允许此变量为空,这时就应考虑使用reference(引用)。

但是,下面这样的东西又是何种意义呢?

char *pc=0;           //将pointer设定为空
char&  rc=*pc;       //让reference代表null pointer的解引值

这种代码是不可接受的。其结果不可预知(C++对此没有定义),编译器可以产生任何可能的输出。所以应当慎重使用pointer和reference。

由于reference必须代表某一个对象,C++因此要求references必须要有初值,否则会编译错误:

string &str;           //错误!!!references必须被初始化
string s("wang");   
string &str=s;        //正确,rs执行s

但是pointer就没有这样的限制:

string *str;

没有所谓的null reference这个事实意味着使用references可能会比使用pointers效率更高。因为使用reference之前不需要测试其是否有效。

void printDouble(const double& rd){
	cout<<rd;      //无需测试rd,必然代表某一个double
}

若使用pointers,为程序的严谨性和正确性,必须检测其是否为空:

void printDouble(const double *rd){
	if(rd){             //检查是否为null pointer(空指针)
		cout<<*rd;     
	}
}

另一个重要的差异就是:pointers可以被重新赋值,指向另外一个对象,references却总是指向(代表)它最初获得的那个对象。

string s1("Nanjing");
string s2("Beijing");

string& rs=s1;    //rs指向(代表)s1
string *ps=s2;    //ps指向s2
rs=s2;            //rs仍然代表s1  但是s1的值现在变成了"Beijing"

ps=&s1;          //ps现在指向s1       s1并未发生变化

通常而言,当考虑“不指向任何对象”的可能性时,或是考虑“在不同时间指向不同对象”的能力时,应该采用pointer。前一种情况你可以将pointer设置为null,后一种情况则可以改变pointer的所指对象。而“总是会代表某个对象”,而且“一旦代表了该对象就不能再改变”,那么这时应该选用reference。

当然,还有一些情况需要使用reference,例如实现某些操作符的时候。最常见的就是operator[ ]。这个操作符很特别地必须返回某种“可以被当作assignment赋值对象”的东西:

vector<int> v(10);    //构造一个int类型的vector,大小为10

v[5]=10;   //assignment的赋值对象是operator[ ]的返回值

如果operator[ ]返回pointer,上边最后一条语句必须是:
*v[5]=10;
但这使得v好似指针形成的vector,事实并非如此。所以,应该总是令operator[ ]返回一个reference。

因此可做如下结论:当需要指向某个东西,而且绝不会改变指向其他东西,或是当你实现一个操作符而其语法需求无法由pointer完成,应该选用reference。其他的任何时候,都应使用pointers。

猜你喜欢

转载自blog.csdn.net/weixin_38339025/article/details/89062756