中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
关于class members的声明和初始化的一些
作者:未知 时间:2005-07-27 23:31 出处:CSDN 责编:chinaitpower
              摘要:关于class members的声明和初始化的一些

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

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

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

他是谁?

就是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中声明的次序被初始化“membersclass中声明的次序难道是指它们于内存中布局的次序?这样想好象可以理解,然而如上面的两个access sectiondata在上size在下时,不是说内存布局不一定吗,那么为什么在data 所处的section在下时可以,在上时就不可以呢?

 

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

/// :~


关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有