深入解析 const 关键字:指针、参数、返回值和类成员函数

您所在的位置:网站首页 指针函数的例子及解析图解 深入解析 const 关键字:指针、参数、返回值和类成员函数

深入解析 const 关键字:指针、参数、返回值和类成员函数

2024-07-06 22:54| 来源: 网络整理| 查看: 265

文章目录 const 关键字的理解一、 修饰普通类型的变量二、const 修饰指针变量三、const 作参数传递 和 函数返回值(1)const 修饰函数参数(2)const 修饰函数返回值 四、const修饰类成员函数结尾

const 关键字的理解

const 在 C++ 中是用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数。

C++中, const允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。

使用const有以下好处:

编译器的静态检查:const 可以让编译器在编译时进行静态检查,确保不会对被声明为 const 的值进行修改。如果尝试修改 const 值,编译器将产生错误或警告。

代码可读性和维护性:使用 const 可以清晰地表达代码的语义,指出某个值不会被修改。可以提高代码的可读性,并且在维护代码时能够更好地理解和推理代码的含义。

防止意外修改:通过使用 const,可以避免在代码中意外地修改某个值。特别是当多人协作开发或者代码规模较大时,const 可以起到约束和保护的作用,防止错误的修改。

优化机会:const 还给编译器提供了一些优化机会,因为编译器知道 const 值不会被修改,可以进行一些相关的优化操作,提高程序的执行效率。

👇下面我们看const 关键字的使用👇

一、 修饰普通类型的变量

观察下面的代码:

const int a = 10; int b = a; // 正常赋值 a = 20; // 错误,不能给常量赋值

当使用const修饰普通类型的变量a时,该变量a会被编译器看成常量,而对常量赋值是违法的。

当我们写出如下的代码时,会发生一些出乎意料的情况:

在这里插入图片描述

我们发现,尽管在监视中a的值为20,但最终输出结果依然为10。

这是因为 编译器对常量的优化处理,将常量 a 存储在只读内存区域,并且优化后的指令可能直接使用常量的值。虽然通过指针修改了数据,但是由于常量 a 是不可修改的,所以它的值仍然保持着 10。

上面的例子告诉我们,在c++中,尽量不要修改const修饰的变量。 但我们可以使用volatile 关键字,即下面的写法:

volatile const int a = 10;

当执行上面的代码时,最后结果会输出 “a的值为:20”

这是因为 volatile 关键字告诉编译器,这个变量的值可能会被意外地修改,因此每次使用这个变量时都要从内存中读取,而不是使用已经存在的寄存器中的值。如果没有使用 volatile,编译器可能会对这个变量进行一些优化,例如缓存这个变量的值,这样就无法保证每次使用这个变量时都是最新的值。

二、const 修饰指针变量

const 修饰指针变量有三种情况:

① const 修饰指针指向的内容,则内容为不可变量。 ② const 修饰指针,指针为不可变量。 ③ const 同时修饰指针和指针指向的内容,指针和指针指向的内容都为不可变量。

对于 ①:

即 const修饰的常量指针:指针本身是一个常量(既*ptr是不可变的),不能修改指向地址所存储的值,可以修改其指向地址(ptr)。

// 理解为: const在int*前,所以 int a = 10, b = 20; const int* ptr = &a; // 修改指向地址所存储的值是不合法的 *ptr = 20; // 错误,编译器会报错 // 修改指向的地址是合法的 ptr = &b; // 合法,可以修改指针指向的地址

对于②:

即 const修饰的指针常量:指针指向的是一个常量,不能通过指针修改所指向地址处的值,但可以修改指针指向的地址。

int a = 10, b = 20; int* const ptr = &a; // 修改指向地址所存储的值是合法的 *ptr = 20; // 合法,可以修改指向地址处的值 // 修改指针指向的地址是不合法的 ptr = &b; // 错误,编译器会报错

对于③:

即 const同时修饰指针和常量:既不能修改指针本身,也不能通过指针修改所指向地址处的值。

int a = 10, b = 20; const int* const ptr = &a; // 修改指向地址所存储的值是不合法的 *ptr = 20; // 错误,编译器会报错 // 修改指针指向的地址是不合法的 ptr = &b; // 错误,编译器会报错 三、const 作参数传递 和 函数返回值 (1)const 修饰函数参数

const 修饰 函数参数有以下三种情况:

const修饰的值传递参数 void func(const int num) { // 不能修改num的值 // ... }

在这种情况下,形参 num 被声明为常量,函数内部不允许修改它的值。

const修饰的指针传递参数 void func(const int* ptr) { // 不能修改ptr所指向地址处的值 // ... }

这里 ptr 是一个指向常量整数的指针,函数内部不能通过指针修改所指向地址处的值,但可以修改指针本身。

const修饰的引用传递参数 void func(const int& ref) { // 不能修改ref所引用的值 // ... }

在这种情况下,引用 ref 被声明为常量,函数内部不允许修改它所引用的值。

(2)const 修饰函数返回值

const 修饰返回值一样有下面三种情况:

const 修饰返回值为常量: const int func() { // ... return 10; }

在这种情况下,函数 func() 的返回值被声明为常量,外部代码不能修改返回值。

const 修饰返回指针类型的函数 int* const func() { // ... static int num = 10; return # }

这里 int* const 表示返回值是一个指向整数的常量指针。使用 const 修饰的指针表示指针本身的值是常量,外部代码不能修改指针指向的地址。但可以通过指针修改所指向地址处的值。

const 修饰返回引用类型的函数 const int& func() { // ... static int num = 10; return num; }

在这种情况下,返回值是一个指向整数的常量引用。使用 const 修饰的引用表示外部代码不能通过引用修改其所引用的对象。

四、const修饰类成员函数

const 修饰类成员函数,其目的是防止成员函数修改被调用对象的值,如果我们不想修改一个调用对象的值,所有的成员函数都应当声明为 const 成员函数。

注意:const 关键字不能与 static 关键字同时使用,因为 static 关键字修饰静态成员函数,静态成员函数不含有 this 指针,即不能实例化,const 成员函数必须具体到某一实例。

有下面两种类型:

const 修饰返回引用类型的函数 class MyClass { public: void func() const { // ... } };

在这种情况下,成员函数 fnc() 被声明为 const 成员函数。const 成员函数表示该函数不会修改类的成员变量。

在 const 成员函数中,不能修改非静态成员变量(除非是 mutable 修饰的成员变量),也不能调用非 const 的成员函数。

const 修饰返回值为常量的成员函数 class MyClass { public: int getValue() const { // ... return value; } private: int value; };

在这种情况下,成员函数 getValue() 被声明为 const 成员函数,并且返回值的类型是 const。这表明该成员函数不会修改类的成员变量,并且返回值在外部代码中不能被修改。

结尾

使用 const 修饰类成员函数可以提供额外的安全性和约束,通过 const 修饰的成员函数,编译器可以对其进行一些优化,在某些情况下还能够调用 const 成员函数来访问 const 对象。同时,也能够帮助开发人员识别和避免意外的修改操作。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3