const的用法

  以前看文章都说const修饰变量代表着“只读”,而自己却对const和指针混合修饰变量时常常搞混,今天就来通过代码探讨const的用法。

1. const修饰普通变量(有以下两种写法)

  const TYPE value;

      TYPE const value;

  这两种写法在本质上是一样的。都表示:const修饰的类型为TYPE的变量 value 是不可变的。

2. const修饰指针类型的TYPE

  A:const char *pContent;      // 对其加上括号为:const (char) *pContent;  A和B效果相等

  B:char const *pContent;      // 对其加上括号为:(char) const *pContent;  A和B效果相等

  C:char * const pContent;     // 对其加上括号为:(char) * const pContent;

  D:const char * const pContent;

  对于A,B,const修饰的是 (*pContent)。其中 pContent为指向char类型的指针,*pContent则表示该指针指向内存空间里的值。既然const修饰的是 (*pContent),也就是说指针pContent指向的内容值为常量,不能修改,但是pContent指针可以修改。(以下通过函数解释说明)

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     char a = 5, b = 6;     // 定义两个char变量
 6     const char *pContent;  // 定义一个char类型的指针
 7 
 8     pContent = &a;   // 指针pContent指向a的地址,此时*pContent=5
 9     printf("*pContent = %d\n", *pContent);
10 
11     pContent = &b;   // 把指针pContent重新指向b的地址,编译运行都OK,此时*pContent=6
12     printf("*pContent = %d\n", *pContent);
13 
14     (*pContent)++;   // 试图让(*pContent)的值加1,此处编译出错,因为(*pContent)的值不能修改
15     printf("*pContent = %d\n", *pContent);
16     return 0;
17 }

  对于【char * const pContent】,const修饰的是指针pContent,所以指针pContent指向的地址不能修改(既然pContent指向的地址不能修改,所以要求定义时需要初始化),但是指针pContent指向的地址里的值可以修改。(以下通过函数解释说明)

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     char a = 5, b = 6;          // 定义两个char变量
 6     char * const pContent = &a; // 定义一个char类型的指针,并初始化指向a的地址
 7     printf("*pContent = %d\n", *pContent);  // 输出 *pContent = 5
 8 
 9     (*pContent)++;                          // 让(*pContent)的值加1,编译运行都OK
10     printf("*pContent = %d\n", *pContent);  // 输出 *pContent = 6
11 
12     pContent = &b;   // 试图修改指针pContent指向b的地址,此处编译出错,因为指针pContent不可变
13     printf("*pContent = %d\n", *pContent);
14 
15     return 0;
16 }

  当然,D则是A,C或者B,C的组合了。此处就不在做代码演示。

 

const的拓展

1. const修饰类对象,类成员函数和类成员变量

  (1)const修饰类的成员函数,则该成员函数不能修改该类的内容(如类的成员变量的值)

  (2)const修饰类的对象,则表示该对象为常量对象,类中的任何成员都不能被修改。const修饰的对象,该对象只能调用该类的const类型的函数,非const类型函数不能调用,因为任何非const成员函数会有修改成员变量的企图。

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Student
 6 {
 7 public:
 8     int  m_dwAge;
 9 public:
10     Student();
11     ~Student();
12     // func1()能修改Student的内容(如修改m_dwage的值)
13     void func1(int a) { m_dwAge = a; cout << ++a; }
14     // func2()被修饰为const了,所以不能修改Student的内容(如以下追加m_dwAge = b;则编译通不过。)
15     void func2(int b) const { cout << ++b; }
16 };
17 
18 Student::Student()  { m_dwAge = 0; }
19 
20 Student::~Student() {}
21 
22 int main()
23 {
24     const Student stu; // 定义一个不能修改Student的对象stu
25     stu.func2( 5 ); // 因为func2()已经被const修饰过了,确保了Student不会被修改,所以此处编译能通过
26     stu.func1( 8 ); // 因为func1()没有被const修饰过,所以fun1有修改Student的企图和能力,所以此处编译出错
27     return 0;
28 }

  (3)const修改类的成员变量,表示成员变量不能被修改,同时他只能在初始化列表中赋值。

class Student

{

public:

  const int m_age;      // 成员变量不能被修改

  ……

  Student(int age) : m_age(age) {};  // 只能在初始化列表中赋值

}

};

2. const常量与define宏定义的区别

  (1)编译器处理方式不同:

    define宏是在预处理阶段展开。

    const常量是编译运行阶段使用。

  (2)类型和安全检查不同:

    define宏没有类型,不做任何类型检查,仅仅是展开。

    const常量有具体的类型,在编译阶段会执行类型检查。

  (3)存储方式不同

    define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。

    const常量会在内存中分配(可以是堆中也可以是栈中)。

posted @ 2015-05-29 17:49  hezhixiong  阅读(313)  评论(0编辑  收藏  举报