• const读书笔记


    Const 的使用读书笔记

    Const的主要主要用法有:

    常变量: const 类型说明符 变量名

    常引用: const 类型说明符 &引用名 
    常对象: 类名 const 对象名
    常成员函数: 类名::fun(形参) const
    常数组: 类型说明符 const 数组名[大小]
    常指针: const 类型说明符* 指针名 ,类型说明符* const 指针名

    • 常变量

          例如:const int a;  或  int const a; 在c语言中声明时必须进行初始化,C++中则没有这个限制。C 标准中,const 定义的常量是全局的,C++中视声明位置而定。

    • 指针常量和常量指针

        const int *x; 指向常整型的指针,x所指向的数据不能被修改

        int *const x; 指向整形的常量指针,x不能指向其它地址;

        const int *const x;指向常整型的常量指针,x所指向的数据不能被修改,同时x自身也不能指向其他地址空间。

        对于const int *x,虽然不能直接修改*x的值,但是我们可以通过下面的方式来修改:

    int i = 10;
    
    const int *x = &i;
    
        int *p = (int *)x;
    
        *p = 11;
    
        //此时i=11; *x= 11;


      同样在函数参数中使用指针常量和常量指针的意义是一样的。   Void f(const char *p);  void f(char *const p);

       

      如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。const 只能修饰输入参数:如果输入参数采用“指针传递”,那么加const 修饰可以防止意外地改动该指针,起到保护作用。例如StringCopy 函数:

    void StringCopy(char *strDestination, const char *strSource);


    其中strSource 是输入参数,strDestination 是输出参数。给strSource 加上const修饰后,如果函数体内的语句试图改动strSource 的内容,编译器将指出错误。

      如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const 修饰。例如不要将函数void Func1(int x) 写成void Func1(const int x)。同理不要将函数void Func2(A a) 写成void Func2(const A a)。其中A 为用户自定义的数据类型。

      对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。

    为了提高效率,可以将函数声明改为void Func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。但是函数void Func(A &a) 存在一个缺点:

        “引用传递”有可能改变参数a,这是我们不期望的。解决这个问题很容易,加const修饰即可,因此函数最终成为void Func(const A &a)。以此类推,是否应将void Func(int x) 改写为void Func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。

    • 常量引用
      引用(reference)就是对象的另一个名字,引用主要用作函数的形式参数。常量引用表示不能通过改引用去修改对应内存的内容。
    int i = 10;
    
    const int &j = i;  //不能通过j改变i的值
    
     
    
    void func(const int& i)
    {
         i = 100; // 错误!不能通过i 去改变它所代表的内存区域。
    } 
    • 常量函数

      在一个函数的签名后面加上关键字const 后该函数就成了常量函数。对于常量函数,最关键的不同是编译器不允许其修改类的数据成员

                 

    class Test
    {
       public:
       void func() const;
    private:
       int intValue;
    };
    void Test::func() const
    {
      intValue = 100;
    }


      上面的代码中,常量函数func 函数内试图去改变数据成员intValue的值,因此将在编译的时候引发异常。

    • 常量对象
      如果我们把一个类定义为常量,我们的本意是希望他的状态(数据成员)不会被改变。那么,如果一个常量的对象调用它的非常量函数会产生什么后果呢?常量对象的状态不允许被修改,又因为非常了得函数可以修改类的成员,因此,通过常量对象调用非常量函数时将会产生语法错误。
    • 常量返回值
      这里就不总结了,具体的可以去看参考文档。

    Const 常量定义相对于define宏定义的优势

           const定义的常量具有数据类型,定义数据类型的常量便于编译器进行数据检查,使程序可能出现错误进行排查。define进行宏定义的时候,不会分配内存空间,编译时会在main函数里进行替换,只是单纯的替换,不会进行任何检查,比如类型,语句结构等,即宏定义常量只是纯粹的置换关系。

    参考资料:

    [1] http://www.phpweblog.net/maple094/archive/2008/05/30/4054.aspx

    [2] http://social.msdn.microsoft.com/Forums/vstudio/zh-CN/b882d9d0-cd67-4eca-930c-7061133c50e6/faq225-const-int-int-const-const-int-const

    [3] http://blog.csdn.net/ego51up_liyanhong/article/details/8624811

    [4]http://www.360doc.com/content/11/0901/11/255982_144947210.shtml#

  • 相关阅读:
    (原创)C++ IOC框架
    【教训】为什么不作备份?!
    【教训】php pcntl_fork无法在web服务器环境下使用
    PHP多进程处理并行处理任务实例
    mysql数据库授权
    PHPUnit学习03使用Mock对象解决测试依赖
    [Inside] How to solve one problem?
    [Inside] What’s the assumptions you are making
    算法面试题解答(六)
    [Inside] System Thinking
  • 原文地址:https://www.cnblogs.com/Jason-Damon/p/3371072.html
Copyright © 2020-2023  润新知