zoukankan      html  css  js  c++  java
  • Effective C++_笔记_条款00_基本术语

    (整理自Effctive C++,转载请注明。整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/

        下面是每一位C++程序员都应该了解的C++词汇。

    1  C++中 声明和定义 的区别

        注意:关于声明和定义的区别,我查了一些资料,和本书也有不一致的地方。暂且按照本书,欢迎指正!。

        所谓声明式(declaration)是指定某个东西的名称和类型,但略去细节。就是通知编译器这有一个与这个名字相关的东西,并且它是这个类型的。例如:

       1: extern int x ;    //对象(object)声明
       2: std::size_t numDigits(int number) ; //函数声明
       3: class Wjdget ;  //类的声明
       4: template<typename T>
       5: class GraphNode ;   //模版声明
    注意:作者将内置类型的变量和用户自定义类型的的变量都视为对象。
     
        所谓定义式(definition)的任务是提供编译器一些声明式所遗漏的细节。对于对象而言定义是编译器为对象分配内存的地点。对函数或函数模版而言, 定义式提供了代码的本体。对于类或者类模版而言,定义式列出它们的成员。例如:
       1: int x ; //对象的定义
       2:  
       3: std::size_t numDigits(int number)    //函数的定义式
       4: {                                    //次函数返回的是整数数字的位数
       5:     std::size_t digitsSoFar = 1 ;
       6:  
       7:     while((number/=10)!=0) ++digitsSoFar ;
       8:     return digitsSoFar ;
       9: }
      10:  
      11: class Widget        //class的定义式
      12: {
      13: public:
      14:     Widget() ;
      15:     ~Widget() ;
      16:     ...
      17: };
      18:  
      19: template<typename T> //模版的定义式
      20: class GraphNode
      21: {
      22: public:
      23:     GraphNode() ;
      24:     ~GraphNode() ;
      25:     ...
      26: };
     

    2  关于构造函数

    2.1 默认构造函数和explicit声明

        对用户自定义的类型的对象而言,初始化由构造函数执行。default构造函数是一个可被调用而不带任何实参者。这样的构造函数要不没有参数,要不就是每个参数都有缺省值。构造函数被声明为explicit,这可以阻止它们被用来执行隐式的类型转换(implicit type conversions),但仍可被用来就行显示的类型转换(explicit type conversions) :

       1: class B
       2: {
       3: public:
       4:     explicit B(int x = 0 , bool b = true ); //default构造函数
       5: };
       6:  
       7: void doSomething (B bObject) ; //函数,接受一个B类型的对象
       8:  
       9: B bObject1 ;  //一个类型为B的对象
      10: doSomething (bObject1) ; //没问题,传递一个B类对象
      11:  
      12: B bObject2(28) ;  //没问题,根据int 28建立一个B类对象(bool参数缺省为true)
      13:  
      14: doSomething (28) ; //错误!doSomething应该接受一个B类对象,而不是int,而int和B之间没有隐式的类型转换
      15:  
      16: doSomething (B(28)) ; //没问题,使用B的构造函数将int显示转换为一个B类对象,从而调用合法

        被声明为explicit的构造函数比no-explicit更受欢迎,因为它们禁止编译器执行非预期的类型转换。除非有非常明确的理由允许构造函数被用于隐式类型转换,否则应声明为explicit。

    2.2 copy构造函数和copy赋值操作符

         copy构造函数被用来“以同型对象初始化自我对象”,copy赋值操作符被用来“从另一个同型对象拷贝其值到自我对象”。例如:

       1: class Widget
       2: {
       3: public:
       4:     Widget();                //default构造函数
       5:     Widget(const Widget& rhs );            //copy构造函数
       6:     Widget& operator= (const Widget& rhs);        //copy赋值操作符
       7:     ...
       8: };
       9:  
      10: Widget w1 ;  //调用default构造函数
      11: Widget w2(w1);  //调用copy构造函数
      12: w1 = w2 ;   //调用copy赋值操作符
      13: Widget w3 = w2 ;//调用copy构造函数

            copy构造函数和copy赋值操作符很容易区别:如果一个新对象被定义,一定会有个构造函数被调用,不可能调用赋值操作。如果没有新对象被定义,就没有构造函数被调用,那么当然就是赋值操作被调用。

     

    3 不明确行为

        由于各种因素,有些C++的行为没有定义:你无法稳定预估运行期会发生什么事。看如下代码:

       1: int* a ;
       2: *a = 12 ;

    这个声明创建了一个名叫a的指针变量,后面那条语句把12存储在a所指向的内存位置。我们在声明指针时没有给它初始化,所以我们无法预测12这个值会存储在什么地方。所以如果程序执行这个赋值操作,会发生什么情况呢?如果你运气好,a的初始值会是个非法地址,这样的赋值语句就会出错,从而终止程序;一个更为严重的情况是:这个指针偶尔可能包含了一个合法的地址。那么那个位置的值就会被修改,虽然你并无意去修改它。像这种类型的错误非常难以捕捉,因为引发错误的代码可能与原先用于操作那个值的代码完全不相关。所以,在对指针进行间接访问之前,必须对其进行初始化。同样的对NULL指针解引用,对数组越界操作,都会引发不明确行为。 

  • 相关阅读:
    java 获取最近三个月的月初和月末日期
    java 字符串与十六进制互转
    @Validated 参数校验及配置
    mybatis 存取Oracle数据库中Blob类型数据
    Java下载服务器文件到前端
    Java实现Oracle拷贝数据插入到MySQL
    保利、绿地用移动质检3.0管进度、质量,让快周转又快又好!
    未造先知,匠心协同-BIM全过程总咨询实践案例赏析-2021版
    大数据资产管理总体框架概述
    “数据资产全生命周期管理”你要知道的九大问题
  • 原文地址:https://www.cnblogs.com/hust-ghtao/p/3712817.html
Copyright © 2011-2022 走看看