01基础议题


基础议题。是的,pointers(指针)、references(引用)、casts(类型转换)、arrays(数组)、constructors(构造函数)——再没有比这些更基础的议题了。几乎最简单的 C++程序也会用到其中大部分特性,而许多程序会用到上述所有特性。尽管你可能已经十分熟悉语言的这一部分,但有时候它们还是会令你吃惊。特别是对那些从 C 转战到 C++的程序员,因为references,dynamic casts,default constructors 及其他 non-C性质背后的观念,往往带有一股黝黯阴郁的色彩。

这一章描述pointers和references 的差异,并告诉你它们的适当使用时机。本章介绍新的 C++转型(casts)语法,并解释为什么新式转型法比旧式的 C 转型法优越。本章也检验了 C 的数组概念及 C++的多态(polymorphism)概念,并说明为什么将这两者混用是不智之举。最后,本章讨论 default constructors(默认构造函数)的正方和反方意见,并提出一些建议做法,让你回避语言的束缚(因为在你不需要 default constructors 的情况下,C++也会给你一个)。只要留心下面各条款的各项忠告,你将向着一个很好的目标迈进:你所编写的软件可以清楚而正确地表现出你的设计意图。

条款 1:仔细区别 pointers和 references

Pointers 和 references 看起来很不一样(pointers 使用“*”和“->”操作符,references则使用“.”),但它们似乎做类似的事情。不论 pointers 或是references都使你得间接参考其他对象。那么,何时使用哪一个?你心中可有一把尺?

首先你必须认知一点,没有所谓的 null reference。一个 reference 必须总代表某个对象。所以如果你有一个变量,其目的是用来指向(代表)另一个对象,但是也有可能它不指向(代表)任何对象,那么你应该使用 pointer,因为你可以将pointer设为 null。换个角度看,如果这个变量总是必须代表一个对象,也就是说如果你的设计并不允许这个变量为 null,那么你应该使用 reference。“但是等等”你说,“下面这样的东西,底层意义是什么呢?”

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

哦,这是有害的行为,其结果不可预期(C++对此没有定义),编译器可以产生任何可能的输出,而写出这种代码的人,应该与大众隔离,直到他们允诺不再有类似行为。如果你在你的软件中还需担心这类事情,我建议你还是完全不要使用references 的好,要不就是另请一个比较高明的程序员来负责这类事情。从现在起,我们将永远不再考虑“reference 成为 null”的可能性。

由于 reference 一定得代表某个对象,C++因此要求 references 必须有初值:

string &rs;			//错误! references必须被初始化。
string s("xyzzy");	
string &rs = s;		//没问题,rs指向s.

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

string *ps;	//未初始化的指针,有效,但风险高。

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

void printDouble(const double &rd
{
	cout << rd;		//不需要测试rd,它一定代表某个double.
}

如果使用 pointers,通常就得测试它是否为 null:

void printDouble(const double *pd)
{
	if(pd) {  //检查是否为null pointer.
		cout << *pd;
	}
}

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

string s1("Nancy");
string s2("Clancy");
string &rs = s1;    //rs代表s1
string *ps = &s1;    //ps指向s1.
rs = s2;            //rs仍然代表s1,但是s1的值现在变成了"Clancy".
ps = &s2;            //ps现在指s2, s1没有变化。

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

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

vector<int> v(10);	//产生一个int vector大小为10。vector是C++标准程库(见条款35)提供的一个template.
v[5] = 10;			//assignment的赋值对象是operator[]返回值。

如果 operator[] 返回 pointer,上述最后一个语句就必须写成这样子:

*v[5] = 10;

但这使 v 看起来好像是个以指针形成的 vector,事实上它不是。为了这个因素,你应该总是令 operator[] 返回一个 reference。条款 30 有一个例外,十分有趣。因此,让我做下结论:当你知道你需要指向某个东西,而且绝不会改变指向其他东西,或是当你实现一个操作符而其语法需求无法由 pointers 达成,你就应该选择references。任何其他时候,请采用 pointers。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值