| 首页 | 新闻 | 网页 | 设计 | 色彩 | 原创 | 视觉 | 素材 | 动漫 | 酷站 | 策划 | 文案 | 访谈 | 运营 | 编程 | 数据库 | 服务器 | 下载 | 图库 | 
您的位置: 幽幽天空 > 网页 > 编程开发 > Visual C++教程 > 文章正文 用户登录
HiShop网店系统一
TOM ULINK新闻联盟
TinyURL免费缩短网
苏能科技100M/FTP
Flash Remoting -
flashremoting实践
Loading制作之 计
Flash8 Remoting 
再探FlashCom的HT
使用 Flash Remot

Thinking again in C++(五)深入认识对象初始化           

Thinking again in C++(五)深入认识对象初始化

作者:佚名 来源:CSDN 作者: cphj 更新:2006-8-25 21:05:35 错误报告 我要投稿

    爱死Thinking in系列了,所以起了这个名字。本文的思想也部分来至于这套书,或参照对比,或深入挖掘,或补益拾慧,或有感而发,既包括Thinking in C++,甚至也包括Thinking in Java。

                          Thinking again in C++(五)深入认识对象初始化

    关键字:C++,初始化,initialization,对象,object


    来自实际项目的一段代码,简化形式如下:
 switch (t)
 {
 case 0:
  int a = 0;
  break;
 default:
  break;
 }
    有什么问题吗?似乎没有。请用编译器编译一下……
    嗯?!一个错误“error C2361: initialization of 'a' is skipped by 'default' label”。这怎么可能?
    几番思琢,悟出解释:C++约定,在块语句中,对象的作用域从对象的声明语句开始直到块语句的结束,也就是说default标号后的语句是可以使用对象a的。如果程序执行时从switch处跳到default处,就会导致对象a没有被正确地初始化。确保对象的初始化可是C++的重要设计哲学,所以编译器会很严格地检查这种违例情况,像上述的示例代码中default语句后面并没有使用a,但考虑到以后代码的改动可能无意中使用,所以一样被封杀。
    明白了原因,解决起来就很容易了。只要明确地限制对象a的作用域就行了。
 switch (t)
 {
 case 0:
  {  //added for fix problem
  int a = 0;
  break;
  }  //added for fix problem
 default:
  break;
 }
    如果确实需要在整个switch语句中使用对象a,那就把int a = 0;移到switch语句之前即可。不过从原先的语句看,其意图似乎并不是这样的,所以推荐前面的解决方案。


    结束了吗?没有。让我们继续考究错误提示信息中“initialization”(也就是初始化)的确切含义。C++很看重初始化,所以往往会给我们造成一种错觉,似乎对象在定义处一定会经过初始化过程。真实情况如何呢?还是用实例来证明吧。
 switch (t)
 {
 case 0:
  int a;
  a = 0;
  break;
 default:
  break;
 }
    编译,这次没有报错。很明显int a;定义了对象,但没有进行初始化,否则就应该报告原先的错误。
    再看看用户自定义类型。
 class B
 {
 };

 switch (t)
 {
 case 0:
  B b;
  break;
 default:
  break;
 }
    编译结果也没有错误,所以没有提供构造器的类仍然没有初始化过程。
    如果给类加入构造器,情况就不同了。
 class B
 {
 public:  //added for initialization
  B(){} //added for initialization
 };
    这样就能重现原先的错误。证明有了构造器,编译器就将进行初始化处理并对之进行安全检查。


    从上面的实验,可以直观地体验到一些基本的C++观念和原理,并提高认识深度。
    1.int a = 0;既是声明也是定义,还包括初始化;int a;是声明还是定义依上下文而定,但如果是定义就不会包括初始化;a = 0;仅仅是赋值语句,在此句前对象已经存在了。
    2.为了避免不必要的开销,默认情况下,即程序员没有在代码中明确指示时,编译器不提供初始化过程。某些需要确保初始化的类,请提供构造器。这里透露出一个C++的设计哲学:通常你会面对多种选择,所以请精确地控制代码,其收益则是可以自由取舍调配的安全性、速度、内存开销等程序特性。
    3.严密注意程序中标号的使用情况,特别是case、default等常规标号,否则他们可能会破坏对象的正确状态。如果提供了对象初始化,则能够获得编译器的额外帮助。

文章录入:skyuu    责任编辑:skyuu 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    发表评论:
    姓名:  评 分: 1分 2分 3分 4分 5分
     
  • 严禁发表危害国家安全、政治、黄色淫秽等内容的评论。
  • 用户需对自己在使用幽幽天空服务过程中的行为承担法律责任。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表机友个人观点,与本网站立场无关。