【八股文 01】const 关键字

发布时间 2023-07-19 11:50:06作者: 她爱喝水

1 const 含义

被它修饰的值不能改变,是只读变量。必须在定义的时候就给它赋初值

2 const 作用

1、修饰变量,说明该变量不可以被改变

2、修饰指针,分为指向常量的指针(pointer to const)和自身是常量的指针(常量指针,const pointer)和前面两种的组合:指向常量的常指针

3、修饰引用,指向常量的引用(reference to const),用于形参类型,即避免了拷贝,又避免了函数对值的修改

4、修饰成员函数,说明该成员函数内不能修改成员变量

3 const 与指针

const 与指针分别 3 种

  • 指向常量的指针(pointer to const)

  • 自身是常量的指针(常量指针,const pointer)

  • 前面两种的组合:指向常量的常指针

3.1 指向常量的指针(pointer to const)/ 底层 const

指向常量的指针(pointer to const):定义了一个指针,这个指针指向一个只读的对象,不能通过该指针来改变这个对象的值。

特点:强调的是指针所指向的对象的不可改变性

底层 const:底层 const(low-level const)表示指针所指得对象是一个常量

形式:

const 数据类型 *指针变量 = 变量名;
数据类型 const *指针变量 = 变量名;

示例代码:

int a = 2;
int b = 3;

// 以下两种写法都可
const int *p = &a;
int const *p = &a;

// 更改
*p = 10;    // 错误,不可更改指向对象的值
*p = &b;    // 正确,可以指向别的对象
a = 10;     // 正确,在原对象上修改

3.2 自身是常量的指针(常量指针,const pointer)/ 顶层 const

自身是常量的指针(常量指针,const pointer):定义了一个指针,这个指针的值只能在定义时初始化。

特点:强调的是指针的不可改变性

顶层 const:顶层 const(top-level const)表示指针本身是一个常量

形式:

const 数据类型 *指针变量 = 变量名;
数据类型 const *指针变量 = 变量名;

示例代码:

int a = 2;
int b = 3;

int *const p = &a;

// 更改
*p = 10;     // 正确,可以改变指向对象的值
p = &b;      // 错误,不可指向别的对象
a = 10;      // 正确,在原对象上修改

3.3 指向常量的常指针

指向常量的常指针:是前面两种指针类型的组合(3.1,3.2)

特点:既不可改变指向的地址 且 指向的对象的内容不可透过指针修改

形式:

const 数据类型 *const 指针变量 = 变量名;

示例代码:

int a = 2;
int b = 3;

const int *const p = &a;

// 更改
*p = 10;   // 错误,不可更改指向对象的值
p = &b;    // 错误,不可指向别的对象
a = 10;    // 正确,在原对象上修改

3.4 记忆方式

第一种方式:利用英文从右边往左边读,并且以 to 为分界,to 之前为描述指针的特性,to 之后为描述指针指向的对象的特性

// (1) p is a pointer to const char
// (1) p 是一个指针指向 const char,即指针所指向的 char 变量的值不可透过指针修改
const char *p; 
char const *p; 

//(2)p is a const pointer to char
//(2)p 是一个 const 指针指向一个 char,即 p 不可改变指向的地址
char *const p; 

//(3)p is a const pointer to const char
//(3)p 是一个 const 指针指向 const char,即 p 不可改变指向的地址,也不可改变指向的对象的值
const char *const p; 

第二种方式:

如果 const 位于 * 的侧,则 const 就是用来修饰指针所指向的对象,即指针指向的对象不可透过指针修改
如果 const 位于 * 的侧,则 const 就是修饰指针本身,即指针本身是常量,不可改变指向的地址

3.5 小结

1、当指向的目标特性为 const,则指针指向的对象的内容不可透过指针修改

2、当指针被加上 const 特性,则指针不可改变指向的地址

3、当上述两种都包含的情况,则指针不可改变指向的地址 且 指针指向的对象的内容不可透过指针修改

4 const 与引用

只有一种

  • 对常量的引用(reference to const)
  • 没有 const reference,因为引用只是对象的别名,引用不是对象,不能用 const 修饰

4.1 对常量的引用(reference to const)- 简称常量引用

特点:不能修改他所绑定的对象

形式:

const 数据类型 &引用变量 = 变量名;

示例代码 1 引用及其对应的对象都是常量:

const int a = 2;

const int &reference1 = a;  // 正确:引用及其对应的对象都是常量
int &reference2 = &a;       // 错误:不能让一个非常量引用指向一个常量对象

reference1 = 10;            // 错误:常量引用不不能修改他所绑定的对象

示例代码 2 引用为常量,其对应的对象不是常量:

int a = 2;

const int &reference1 = a;  // 正确:引用是常量,其对象不是常量
int &reference2 = &a;       // 正确:引用和其对象都不是常量

reference1 = 10;            // 错误:常量引用不不能修改他所绑定的对象
reference2 = 10;            // 正确:普通引用可以修改他所绑定的对象

5 const 与函数

5.1 const 修饰函数返回值

示例代码:

const int function5();      // 返回一个常数
const int* function6();     // 返回一个指向常量的指针变量,使用:const int *p = function6();
int* const function7();     // 返回一个指向变量的常指针,使用:int* const p = function7();

5.2 const 修饰函数参数

示例代码:

void function1(const int Var);           // 传递过来的参数在函数内不可变
void function2(const char* Var);         // 参数指针所指内容为常量
void function3(char* const Var);         // 参数指针为常量
void function4(const int& Var);          // 引用参数在函数内为常量

6 const 与类

示例代码:

class A
{
private:
    const int a;                // 常对象成员,可以使用初始化列表或者类内初始化

public:
    // 构造函数
    A() : a(0) { };
    A(int x) : a(x) { };        // 初始化列表

    // const可用于对重载函数的区分
    int getValue();             // 普通成员函数
    int getValue() const;       // 常成员函数,不得修改类中的任何数据成员的值
};

void function()
{
    // 对象
    A b;                        // 普通对象,可以调用全部成员函数
    const A a;                  // 常对象,只能调用常成员函数
}

7 const 与 #define

8 参考资料

1、《C++ Primer 第五版》- 2.4 const 限定符

2、const那些事 - 作者 Light-City - https://light-city.github.io/basic_content/const/#4

3、interview - 作者 huihut - https://github.com/huihut/interviewhttps://interview.huihut.com/#/?id=const