zoukankan      html  css  js  c++  java
  • const 使用小结

    is2120@csdn
    1. 修饰变量,使得在初始化变量值后不能在修改其值。

    // 无const修饰
    int  x = 4;
    x = 10;

    // 有const修饰
    const int x = 2;
    x = 10; // err

    2. const替代#define的好处
    在调试时可以看见变量名,而#define后调试时只能看见值
    避免了宏定义带来的种种麻烦(宏是直接的文本替代,这会带来问题)

    3. const 和指针
    const int x;      // constant int
    x = 2;            //x 非法--不能修改x

    const int* pX;    // 一个指向const int的指针,指针值可变
    *pX = 3;          //x 不能使用px修改一个const int的值
    pX = &someOtherIntVar;      // 但是px可以指向其他的地方

    int* const pY;              // 指针为const,其所指向的值类型为int
    *pY = 4;                    // 使用pY修改int的值
    pY = &someOtherIntVar;      //x 不能指向其他地方

    const int* const pZ;        // const指针,指向const变量
    *pZ = 5;                    //x
    pZ = &someOtherIntVar;      //x

    4. const、指针和类型转换
    int y;
    //z 此处const的含义是:并不是说指向的变量必须是const,而是说你不能使用该指针来变更其指向的值
    const int* pConstY = &y;  //x 不能使用pConstY来修改y
    int* pMutableY = &y;      //x 能使用pMutableY来修改y
    *pMutableY = 42;

    5. c++中不允许轻易绕过const属性
    赋值操作符不能没有经过明确的抓换而将一个const int * 转换成int *
    c++不支持将一个const type 类型的变量转换成为type类型的标准转换。
    const int x;             // x不可修改

    const int* pX = &x;

    *pX = 4;                 //x 错误

    int* pInt;       // 一般类型的指针(非const)
    pInt = pX;       //x 错误,不能将一个const int * 指针转换成为 int *

    int *pInt;   //
    pInt = &x;   // 错误,不能将const int* 转换成 int *

    6. 强制编译器进行类型转换(const type -> type)
    const int x = 4;
    const int* pX = &x;

    cout << x << endl;

    // 强制将 px 由 const int* 转换成 int *
    int* pX2 = (int *)pX;
    *pX2 = 3;                  //错--结果是未定义的(UB)

    cout << x << endl;        //

    上述代码在vc中所产生的会变代码
    ASSEMBLER OUTPUT                       C++ CODE
    Mov   eax, DWORD PTR _pX$[ebp]         int* pX2 = (int *)pX;
    Mov   DWORD PTR _pXX$[ebp], eax
    Mov   eax, DWORD PTR _pXX$[ebp]        *pX2 = 3;
    Mov   DWORD PTR [eax], 3
    Push  OFFSET FLAT:?endl@@.........     cout << x << endl;
    Push  4

    注意到这里的PUSH 4,即编译器觉得你定义了一个const变量,在使用的时候就没有解引用而直接引用其值了(优化的结果)。

    7. const_cast 操作符
    使用 const_cast 去除变量的常量性。
    const int x = 4;      //
    const int* pX = &x;   //

    cout << x << endl;    // prints "4"

    int* pX2 = const_cast < int* > (pX);   // 将pX显式转换成非const

    *pX2 = 3;           // 未定义(BH)
    cout << x << endl;   //
    同c style的强制类型转换不同的是,const_cast 只会改变变量的常量性,而不会改变变量的类型。

    8. const 存储与字符常量
    char* szMyString = "Hello world."; // 定义了一个字符常量
    szMyString[3] = 'q';         // 未定义,试图修改静态缓冲区
    标准认为这些字符常量的类型是const,一个字符常量的类型是一个const chars的数组。

    c++中不能将一个const type标准转换为 type 类型。
       const char constArray[] = { 'H', 'e', 'l', 'l', 'o', '/0' };
       char nonConstArray[] = { 'H', 'e', 'l', 'l', 'o', '/0' };
       char* pArray = constArray;            // illegal
       char* pArray = nonConstArray;         // legal
    但是这样又是可以的
       // should be illegal - converts array of 6 const char to char*
       char* pArray = "Hello";
    这是为了和旧式的c代码兼容

    9. 同样的字符常量可能指向同一个内存区域
    "The /GF option causes the compiler to pool strings and place them in read-only memory.

    例如以下代码
    #include <stdio.h>

    int main()
    {
       char* szFirst = "Literal String";
       char* szSecond = "Literal String";

       szFirst[3] = 'q';
       printf("szFirst (%s) is at %d, szSecond (%s) is at %d/n",
             szFirst, szFirst, szSecond, szSecond);

       return 0;
    }
    在启用“string pooling”后,其输出为
    szFirst (Litqral String) is at 4266616, szSecond (Litqral String) is at 4266616
    (我这里是运行错误)

    10. 总是使用 const
    class Person
    {
       public:
          Person(char* szNewName)
          {
             // make a copy of the string
             m_szName = _strdup(szNewName);
          };

          ~Person() { delete[] m_szName; };

          const char* const GetName() const
          {
             return m_szName;
          };

       private:
         
          char* m_szName;
    };


    在返回指针、使用指针作为参数时,总是想想是否适用const。
    这样会使得编程变得比较轻松。

    11. const 成员函数
    const成员函数:该函数不会修改函数成员并且不会调用非const成员函数。
    const 或者 non-const 对象都可以调用 const 成员函数
    const对象不能调用non-const成员函数

    12. The Mutable Storage Specifier
     A mutable member variable can be modified even by const member functions.
    即便是一个const 成员函数也能修改一个 mutable 成员变量。
    class MyData
    {
       public:
          /*
          the first time, do calculation, cache result in m_lCache, and set
          m_bCacheValid to true. In subsequent calls, if m_bCacheValid is true
          then return m_lCache instead of recalculating
          */

          long ExpensiveCalculation() const
          {
             if (false == m_bCacheValid)
             {
                m_bCacheValid = true;
                m_lCache = ::SomeFormula(m_internalData);
             }
             return m_lCache;
          };

          // change data and set m_bCacheValid to false to force recalc next time
          void ChangeData()
          {
          };

       private:

          data m_internalData;
          mutable long m_lCache;
          mutable bool m_bCacheValid;
               
    };

    is2120@csdn

  • 相关阅读:
    一个简易的MySQL性能查询脚本
    pt-osc原理、限制、及与原生online-ddl比较
    Netstat Commands for Linux Network Management
    MySQL 资源大全中文版
    自增表死锁问题分析及处理
    MySQL自带的性能压力测试工具mysqlslap
    iOS in-app purchase详解
    iOS 将Excel导入到SQLite3的过程
    iOS iTuns Connect官方配置教程
    OpenGL 知识二
  • 原文地址:https://www.cnblogs.com/IS2120/p/6746060.html
Copyright © 2011-2022 走看看