const、 volatile 和mutable

本文详细介绍了C/C++中的const、volatile和mutable三种类型的使用场景和区别,包括const修饰变量、函数参数、类对象/引用、成员数据以及成员函数的返回值,volatile关键字的应用及注意事项,mutable的作用及其实例。通过对比const和define的特点,帮助开发者更好地理解这些类型的特性,以提高代码质量和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

const, volatile mutableC/C++中的三种类型限制付。三者具有不同的优点,不同的用途。

下面就三者在不同方面的应用进行一个总结。

一、const:在最初的C语言中const用来修饰变量和指针以及函数参数,但在C++const的用途进一步被拓展。const更确切的解释应该是read only

1const 修饰变量:

一般有两种写法:const type var; type const var;两者的意义相同。

但对于指针类型变量const有三种不同的意义:

const type *pvar;/ int const * pvar; 指向常量的指针。

type * const pvar;指针常量,pvar是不可改变的。

const type * constpvar; 指针和其指向的内容均不可改变。

2const 修饰函数参数

const修饰函数参数一般表示函数体中不能修改函数参数的值。

void func(consttype var); // 无意义,const对值传递没有意义;

void func(type *const pvar);//无意义,函数参数为指针常量,是对指针的值传递,因此也没有意义。

void func(consttype *pvar); // 可以,指针所指内容不能改变

void func(consttype & rvar);// 可以,引用参数内容不能改变

3const修饰类对象/对象指针/对象引用

const修饰类对象/对象指针/对象引用,表示类中的任何内容都不能改变。且被const修饰的对象不能调用类中的非const函数。

4const修饰成员数据

类的const成员数据不能在类中进行初始化,必须利用初始化列表进行初始化,不同类的const数据成员可以不同。如果必须要在类中初始化数组时,可以利用enum类型变量。如:

 

class example
{
	public:
	example() {}
	~example(){}
	private:
	enum{size_a = 100, size_b =200}; //此时不能用const int size_a 
//= 100 和 const int size_b =200 代替
	int arr_a[size_a];
	int arr_b[size_b];
};

 

 

5const 修饰成员函数的返回值

1)   这种情况一般只会发生在运算符重载中,在一般的成员函数很少会用到,因为这样做了之后会规定返回的对象属性为const,那么该对象就只能调用类中的公共的数据成员和const函数。

2)   返回const type *指针,表示指针指向的内容不能被改变,且该返回值只能赋给const type*的指针。

3)   返回const type &引用,这种情况比较少见。返回值采用引用传递的情况一般只出现赋值函数中,目的为了实现链式表达式。

constdefine的区别

1). 编译器处理方式不同

      define是在预处理阶段展开

      const是在编译阶段进行处理

2). 类型和安全检查不同

      define没有类型和安全检查

      const具有类型和安全检查

3). 存储方式不同

      define定义的宏变量在内存中有若干个拷贝,在预编译阶段执行宏展开(直接的替换)。

      const定的变量在内存中只有一份拷贝(因为它是全局的只读变量,存储在静态区)。

二、volatile关键字

volatile本意是“易变的”,其是一种类型修饰符,用它声明的变量表示可以被某些编译器位置的因素改变,比如操作系统,硬件,或其它线程等。遇到这个关键字声明的变量,编译器不会对访问该变量的代码进行优化,从而提供对特定地址的稳定访问。

volatile应用的例子:

1). 并行设备的硬件寄存器(如状态寄存器)

2). 一个中断服务子程序中会访问到的非自动变量(全局变量和静态变量)

3).多线程应用中被多个任务共享的变量

更进步的有关volatile的问题:

1).一个参数既可以是const有可以是volatile吗?为什么?

可以,举个例子:状态寄存器,它是volatile因为它是可能被外界改变的,但它同时也是const的因为它不希望被程序改变。

2).一个指针可以是volatile的吗?

可以,但是这类的事情不常见,比如一个中断服务子程序修改一个纸箱buffer的指针。

3).判断下面程序是否有错误:

int square(volatile  int *ptr)
{
	return *ptr * *ptr;
}


 

该函数的目的是返回*ptr的平方,但是由于声明了*ptrvolatile的,因此编译器会将其解释为:

int square(volatile int *ptr)
{
	int a = *ptr;
	int b = *ptr;
	return a*b;
} // 这里a和b的值可能不同


 

正确的书写方法应该是

int square(volatile int *ptr)
{
	int a = *ptr;
	return a*a;
}

三、 mutable

mutable的意思是“可变的,易变的”,其与const是反义词。它是用来突破const的限制的。比如一个类的const成员函数是不能修改类的状态的,但是如果我们需要修改一些与类的状态无关的数据成员的时候,我们可以将该数据成员声明为mutable



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值