关于class members的声明和初始化的一些

王朝other·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

清早,风从窗外踏进,穿堂而过。我还在回味刚刚的梦境,和梦境中呈现的纯真的友谊所带来的泪水。

“怎么,电脑找到了吗?”我起身跑到了隔壁,看到一伙人坐在那高谈阔论,一洗昨日的颓废。

“差不多了,昨晚警察审讯了一夜,他交代了。”

“他是谁?”

“就是4室的那个,高高的,黑黑的。”

“他?难以置信……我曾屡屡和他亲切地交谈,他『看上去』那么……!”

不过这让我想起了C++。

来看一个例子(取自Scott Meyers 的EC条款13),目的是为解决C/C++程序员不可自定义数组下界的“痛苦”(也许是痛苦,也许是福音),不过这不是今天的重点。

template<class T>

class Array {

public:

Array(int lowBound, int highBound);

...

private:

vector<T> data; // 数组元素安放于vector<T>容器

size_t size; // 数组大小

int lBound, hBound; // 下界,上界

};

template<class T>

Array<T>::Array(int lowBound, int highBound)

: size(highBound - lowBound + 1),

lBound(lowBound), hBound(highBound),

data(size) {}

这个程序唯一的好处也许是:你的编译器或者老板(如果是老板,你最好别跟他谈提薪的事!),决不会因之而给你宽恕或怜悯,乃至任何有关成功的妄想(人们总是很容易地就相互同情,所以有时候冷漠的拒绝完全堪称一项“好处”)。

来看看它干了什么。它小心翼翼地先初始化size,然后再用size去初始化data。不过,这只是『看上去』罢了。编译、组建都没有问题,可是运行时,灾难来了。

原因是data在初始化时,size却还未定义(undefined)。这是不能容忍的。C++没有Java那么“博爱”(有人称之为“溺爱”),在Java的世界里,对象在使用之前必须要被初始化才行,编译器会强制你这么做(这可能就是“溺爱”的原由)。C++就没有这么周到的家境了,如前面的size,在你显式地(explicit)初始化它之前,鬼知道它会是什么(也许是0,也许不是)!

先知Scott Meyers告诉我们,class members以它们于class中声明的次序被初始化,而不是以它们出现于初始化列表中的次序被初始化。所以,最好让你的初始化列表的成员次序与它们声明的次序相吻合。(具体原因请翻阅Meyers的书)。

C++不会错,错的只会是你,是你不懂标准就乱来。其实问题解决起来还算简单,只要按照下面这样改了就行——

……

private:

size_t size;

int lBound, hBound;

vector<T> data;

……

template<class T>

Array<T>::Array(int lowBound, int highBound)

: size(highBound - lowBound + 1),

lBound(lowBound), hBound(highBound),

data(size) {}

现在世界重新恢复秩序,人们(程序员们)从此安居乐业……

且慢,假若再这样地改一下呢——

template<class T>

class Array {

public:

Array(int lowBound, int highBound);

...

// 将members安放于两个access section

private:

size_t size;

int lBound, hBound;

private:

vector<T> data;

};

初始化列表照写如上,编译,运行,没有问题。

若这样改呢——?

// 交换两个access section的顺序

private:

vector<T> data;

private:

size_t size;

int lBound, hBound;

初始化列表照写如上,编译,运行,呜——!有问题!

来看看先知Stanley Lippman是怎么说的:C++中凡处于同一个access section的数据,必定保证以其声明次序出现在内存布局当中。然而被放置在多个access sections中的各笔数据,排列次序就不一定了。

我有一些疑惑:Meyers 说“class members以它们于class中声明的次序被初始化”,“members于class中声明的次序” 难道是指它们于内存中布局的次序?这样想好象可以理解,然而如上面的两个access section,data在上size在下时,不是说内存布局不一定吗,那么为什么在data 所处的section在下时可以,在上时就不可以呢?

结论只能是:members于class中声明的次序,不等于它们于内存中的布局(除非它们位于同一access section),而初始化是按声明次序,没必要与内存布局也扯上瓜葛(否则,倘若涉及到派生时,base class与derived class各自成员的内存布局也是不确定的,那岂不更加麻烦?)。

/// :~

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航