Contents
  1. 1. 常量
  2. 2. 指针与常量
  3. 3. const修饰函数的传入的参数
  4. 4. 修饰函数返回值
  5. 5. const修饰成员函数
  6. 6. 常量与指针
  7. 7. 常量与引用
  • C++ 中的const
  • 采用符号常量写出的代码更容易维护;const最常见的用途是作为数组的界和switch分组标号。分类如下:

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

    常量

    取代了C语言中的宏定义,声明时必须进行初始化(C++中则不然)。const限制了常量的使用方式,并没有描述常量应该如何分配。
    用const声明的变量虽然增加了内存,但是可以保证类型的安全。

    指针与常量

    使用指针涉及到两个对象:该指针和它所指的对象,
    const char *p = greeting; //指针可以改变,但是指针指向的数据不能改变。
    char* const p = greeting; //指针不能改变,但是指针指向的数据可以改变。

    const修饰函数的传入的参数

    将函数传入的参数声明为const,以指明这种参数仅仅是为了效率的原因,同理,将指针参数声明为const,函数将不能修改这个参数所指向的对象。

    修饰函数返回值

    可以修改用户修改返回值。返回值也要相应的付给一个常量和常指针。

    const修饰成员函数

    const_learning中已经讲述过。

    展开来讲:

    常量与指针

    1. 对于常量指针,不能通过该指针改变它所指的内容。
    1
    2
    3
    int i = 10;
    const int *pi = &i;
    *pi = 100;

    这样是会报错的。

    1. 但是,可以使用另外一个指针来修改。
    1
    2
    int *p = (int *)pi;
    *p = 100;

    实际上,在将程序载入内存的时候,会有专门的一块内存区域来存放常量。但是,上面的i 本身不是常量,是存放在栈或者堆中的。我们仍然可以修改它的值。而pi 不能修改指向的值应该说是编译器的一个限制。

    常量与引用

    常量与引用的关系稍微简单一点。因为引用就是另一个变量的别名,它本身就是一个常量。也就是说不能再让一个引用成为另外一个变量的别名, 那么他们只剩下代表的内存区域是否可变。
    int i = 10;
    //正确:表示不能通过引用修改对应的内存的内容
    const int& ri = i;
    //错误!不能这么写
    int& const rci = i

    有必要深入的说明以下,在系统加载程序的时候,系统会将内存分为4 个区域:堆区 栈区全局区(静态)和代码区。从这里可以看出,对于常量来说,系统没有划定专门的区域来保护其中的数据不能被更改。也就是说,使用常量的方式对数据进行保护是通过编译器作语法限制来实现的。我们仍然可以绕过编译器的限制去修改被定义为“常量”的内存区域。


    C++ 中的const

    1. const常量
      const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查

    2. const 修饰类的数据成员。
      const 可以提供封装特性,可以修饰类的数据成员。

      1. 不同的对象其const 数据成员的值可以不同。所以不能在类声明中初始化const 数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。
    1
    2
    3
    4
    5
    class A
    {
    const int size = 100; //错误
    int array[size]; //错误,未知的size
    }
    1. const 数据成员的初始化只能在类的构造函数的初始化表中进行。要想建立在整个类中都恒定的常量,可以采用所谓的“ the enum hack”的补偿的做法。其理论的基础是:“一个属于枚举类型(enumerated type)的数值可权当 ints 使用”
      上述代码可以修改为:
    1
    2
    3
    4
    5
    class A
    {
    enum {size = 100}; //"the enum hack"--令size成为100的一个记号名称
    int array[size]; //it's ok
    }

    枚举常量不会占用对象的存储空间,他们在编译时被全部求值。但是枚举常量的隐含数据类型是整数,其最大值有限,且不能表示浮点数。

    Contents
    1. 1. 常量
    2. 2. 指针与常量
    3. 3. const修饰函数的传入的参数
    4. 4. 修饰函数返回值
    5. 5. const修饰成员函数
    6. 6. 常量与指针
    7. 7. 常量与引用
  • C++ 中的const