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指针解引用,对数组越界操作,都会引发不明确行为。 

  • 相关阅读:
    字符串 CSV解析 表格 逗号分隔值 通讯录 电话簿 MD
    Context Application 使用总结 MD
    RxJava RxPermissions 动态权限 简介 原理 案例 MD
    Luban 鲁班 图片压缩 MD
    FileProvider N 7.0 升级 安装APK 选择文件 拍照 临时权限 MD
    组件化 得到 DDComponent JIMU 模块 插件 MD
    gradlew 命令行 build 调试 构建错误 Manifest merger failed MD
    protobuf Protocol Buffers 简介 案例 MD
    ORM数据库框架 SQLite 常用数据库框架比较 MD
    [工具配置]requirejs 多页面,多入口js文件打包总结
  • 原文地址:https://www.cnblogs.com/hust-ghtao/p/3712817.html
Copyright © 2011-2022 走看看