C++基础之关键字——const,volatile,mutable,auto,register,static,extern

const

const表示所限定的描述符是不可变的。const主要的应用场景有修饰变量、修饰指针、修饰函数参数、修饰类的成员函数、修饰数据成员、修饰类的对象,const修饰函数返回值。下面分别说明一下:

修饰变量

const int a;
int const a; 

两种方式效果相同,都表示变量a是一个常量是不可变的。

修饰指针
与修饰变量类似有两种写法,但是意义不同:

const int * p;
int * const p;
const int * const p;

第一种写法意思是: 创建的指针a所指向的内容是不能被修改的,也就是*p的不能修改,不能给*p赋值。
第二种写法意思是: 指针p不能改变,不能够指向其他的int型指针也就是不能给p赋值
第三种写法是前两种的结合, p所指向的指针和指针内容不都能修改
记忆技巧:我是通过离谁近区分的,第一种离数据类型近说明数据不能变, 第二种离*近也就是指针不能变。

修饰函数参数
传给函数的参数一般是通过值传递的,所以函数内处理的是参数的一个副本,加不加const都没有意义,所以只针对指针和引用是有作用的。

int func(const int * p)
int func(int * const p)
int func(int & a)

第一种写法表示指针p指向的内容不允许改变。
第二种写法是p指向的指针不能修改,这里其实没有意义,p会通过值传递。
第三种写法引用a的内容不允许修改。

修饰类的成员函数
一般写到函数的最后, 用const修饰的类成员函数不能够修改类对象的数据成员,也不能调用任何非const的成员函数。

class A {
    
    
    int func () const;
}

修饰类对象
修饰类的对象的时候,该类的对象只能调用类中的const类型的函数,不能调用其他的函数。

class A {
    
    
	int func1();
	int func2() const;
};

const A a;

a.func1()是可以的,但是a.func2()会报错。

const修饰函数返回值
使用const修饰的返回值要赋值给对应的const变量。

修饰类的数据成员
const修饰的数据成员只是针对对象的常量,在创建对象的时候做初始化,每个对象都有自己的const对象(区别与static)

volatile

volatile指不稳定的,用来修饰变量,它表示该变量不能使用编译器中的一些优化操作,如果使用到该变量的话需要重新从内存中读取数据。

volatile int a =10;

mutable

mutable与const对应,指可变的,可修改的。是为了解除const的限制,被mutable修饰的变量将永远处于可变的状态,即使在const的函数内。举个经典栗子:

class A
{
    
    
	void func1() const;
	int getCount() const; //获取func1被调用次数

private:
	mutable int num;	
}

void A::func1() {
    
    
	num += 1; //正常情况下func1是const函数不能修改数据成员,但是num加了mutable后就可以修改了
}

auto

C语言中的auto修饰的变量说明该变量是自动变量,可以省略。C++中的auto有了更多的含义,主要是通过后面变量的值来自动推断变量的类型。因此auto修饰的变量必须初始化, 定义在一个auto序列的变量必须始终推导成同一类型。

auto a = 1, b = 0.5, c = 'r'

register

register修饰的变量会让编译器尽可能的将变量存在CPU内部寄存器,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。
但是C++的编译优化已经可以自动优化一般也不需要手动添加。

static

static的作用主要有两个:一个是设置作用域;一个是指定声明周期

修饰类中的数据成员
这个与const不同,const修饰的是创建的每个对象都会有属于自己的成员,而static修饰的数据成员是属于整个类,所有的对象共有。属于类的全局变量,static修饰的成员必须要有初始化。

class A 
{
    
    
private:
	static int a;
}

int A::a = 1; //不可以在构造函数内初始化,要在类外初始化

修饰类中的成员函数
与修饰数据成员类似,被修饰的函数说明该函数是全局的函数,属于该类的不属于具体的某个对象,因此只能访问类的静态数据成员,不需要类的实例对象就可以调用。

class A
{
    
    
	static int func();
}

A::func() {
    
    
	.....
	return;
}

A::func();

修饰cpp文件内的全局变量
在cpp内被static修饰的全局变量说明该变量只能在本文件内访问,其他cpp不能访问。如果在头文件中定义static变量,那么包含该头文件的cpp都会有单独的一个变量,不建议这么做。

static int a = 0

修饰cpp文件中的全局函数
与修饰全局变量功能相同,使用static修饰的函数只能在本文件中使用。建议:不要在头文件中声明static全局函数,不要在cpp中声明会被其他文件访问的非static函数,如果多个文件使用要将声明放到头文件中。

static int func();

extern

extern有两个主要功能:第一个用在变量或者函数前面,说明后面的变量或者函数是在别处定义的,这里只是引用;第二个功能是extern c,说明后面的的函数名要保持原始的名称,不需要生成中间函数名,这对c++中调用c接口时会使用。

猜你喜欢

转载自blog.csdn.net/itlilyer/article/details/109201275