C++ - const 关键字

 

const 变量一经赋值,不能修改

若在源代码中,const变量被修改,则编译器会报错 'l-value specifies const object'

(一) 常量指针 vs 指针常量 【面试题2-7】

 1  #include <stdio.h>
 2  
 3  int main()
 4  {
 5      const int x = 1;
 6      int b = 10;
 7      int c = 20;
 8  
 9      const int* a1 = &b;  
10      int* const a2 = &b;
11      const int* const a3 = &b;
12  
13      x = 2;     // wrong! Line 5 const int x =1 赋值 不能修改
14  
15      a1 = &c;   // Right. Line 9 中 const 修饰的是 *a1, *a1为 int 类型,a1本身可以修改
16      *a1 = 1;   // wrong! *a1 是 const, 不能修改,报错 l-value specifies const object
17  
18      a2 = &c;   // wrong! Line 10 中 const 修饰 a2, a2 是 const, 不能修改
19      *a2 = 1;   // right. *a2 是 int 类型,可以修改
20  
21      a3 = &c;   // wrong! Line 11 中  a3 和 *a3 均为 const, 不能修改。 
22      *a3 = 1;   // wrong! Line 11 中  a3 和 *a3 均为 const, 不能修改
23  
24      return 0;
25  }

(二)说明 #define 与 const 的特点及区别 【面试题2-8】

(2.1) #define

1 #define PI 3.1415926 2 float angel; 3 angel = 30 * PI / 180;

#define:程序在预编译期间,会将所有 PI 替换成 ‘3.1415926’, 然后进行编译. 

#define 常量是一个 "Compile-Time" 概念, 因此它存在与程序的代码段,在实际运行中它没有实在意义

(2.2) const

const 变量存在于程序的数据段,并在推展分配了空间。

const常量是一个‘Run-time’的概念。它在程序中确确实实地存在着并可以被调用,传递。

const 有数据类型,#define 没有数据类型。

编译器可以对const 常量进行类型安全检查。

(三)C++ 中 const 有什么作用? 【面试题2-9】

  (1)const 用于定义常量;const 定义的常量,编译器可以对其进行数据静态类型安全检查

    (2)  const 修饰函数形式参数:当输入参数为用户自定义类型和抽象数据类型时,应该将 ‘值传递’ 改为 'const & 址传递', 可以提高效率。

1 void fun(A a);
2 void fun(A const &a);

    以上代码,Line 2 的执行效率比 Line 1 高,因为‘引用传递’不需要产生临时变量,没有构造,复制,析构的过程。但光引用 A& a 有可能改变 a, 因此加上 const

  (3)const 修饰函数的返回值,则返回值不能被修改,同时要求返回值只能赋值给 const 修饰的同类型变量

1 #include <stdio.h>
2 const int fun() {return 1;}
3 int main(){
4     const int m = fun();  // 用 const 变量 接收 返回值 为 const 的函数 的 返回
5     return 0;
6 }

  (4)const 修饰类的成员函数:任何不会修改数据成员的函数都应用 const 修饰,这样,当不小心修改了数据成员或调用了非 const 成员函数时,编译器都会报错。const 修饰类的成员函数形式为

int GetCount(...) const;

【注意】以上表达与 const int GetCount(...) 不同,const int GetCount(...) 表示返回值是 int 类型的常数

【例子】

 1 class Student{
 2     public:
 3       Student(char* name, int age, float score);
 4       void show();
 5       char* getname() const;
 6       int getage() const;
 7       float getscore() const;
 8    private:
 9       char *m_name;
10       int m_age; 
11       float m_score;
12 };
13 
14 Student::Student(char* name, int age, float score):m_name(name),m_age(age),m_score(score){}
15 void Student::show(){
16    cout<<m_name<<"'s age is "<<m_age<<" with score of "<<m_score<<endl;
17 }
18 char* Student::getname() const {return m_name;}
19 int Student::getage() const {return m_age;}
20 float Student::getscore() const {return m_score;}

【注意】类中的const成员函数的定义和实现都需要同时在函数头部的结尾加上 const 关键字。char* getname() const 与 char* getname() 是两个不同的函数原型,若只在一个地方加 const 会导致生命和定义处的函数原型冲突。

  (5)初始化 const 成员变量的 唯一方法是使用初始化列表

 1 class VLA{ // 正确的版本
 2     private: 
 3        const int m_len;
 4        int *m_arr;
 5     public:
 6        VLA(int len);
 7 };
 8 //必须使用初始化列表来初始化 m_len
 9 VLA::VLA(int len):m_len(len){
10     m_array = new int[len];
11 }
class VLA{ // 错误的版本
   private:
       const int m_len;
       int *m_arr;
   public:
       VLA(int len);
};

VLA::VLA(int len){
   m_len = len;  // const int m_len 不能在这里被初始化
   m_arr = new int[len];
}

 

参考 (Reference)

[1] C 和 C++ 程序员面试秘诀-精选最常见的C/C++面试真题: 董山海 

[2] http://c.biancheng.net/view/2230.html

[3] http://c.biancheng.net/view/2223.html

posted on 2020-03-03 06:46  猪伯  阅读(166)  评论(0编辑  收藏  举报

导航