const与volatile

看到const会想到const修饰变量起到保护作用,但只有这个的话还不够,看下面

const

C:

1.0在c语言中在变量前面加上const之后其作用为将此变量定以为常变量(实际上它还是变量只是值不能改)。

看一段代码来证明:

代码1:


从上图就可以知道const修饰的变量在c语言里不能当常量用。但C++可以。

2.0它相当于宏(替换),不同的是宏的替换发生在预处理阶段而const修饰的变量的替换发生在编译阶段。参数检测实在编译阶段执行的,所以const修饰的变量会进行参数检测而宏不会。

3.0 函数的参数值传递是就没必要加const修饰了,因为它本身就不需要保护(只是实参的临时拷贝)。

4.0函数的返回值加上const。有些情况是不可以的。

#include<stdio.h>
const char* Function()
{
	;
}
#include<windows.h>
int main()
{
	char* p="abcde";
	p= Function();
	system("pause");
	return 0;
}
应该报错:如下


所以不要轻易在函数返回值前面加上const

5.0 const修饰指针时,距离谁近修饰谁(不考虑类型名)

int arr[5];
    const int *a = arr; //const 修饰*a,a 是指针,可变; *a 是指针指向的对象,不可变。
    int const *a = arr; //const 修饰*a,a 是指针, 可变;*a 是指针指向的对象,不可变。
    int *const a = arr; //const 修饰 a,a 是指针,不可变;a 指向的对象可变。
    const int *const a= arr; //前一个 const 修饰*a,后一个 const 修饰 a,指针 a 和 a 指向的对象都不可变


注意:1.0 const修饰变量时一定要初始化。

           2.0 const在修饰一个变量时的连续使用。(const int const a=10)在c下是可以的但是不建议使用。

           3.0 const修饰的变量不能出现的位置(也就是常量的位置)例如case:的后面,以及数组的方括号里。

C++:

1.0 const修饰全局变量,和c用法一样。

2.0 const修饰的成员变量,能在成员函数里使用(加了const的成员函数)

#include<iostream>
using namespace std;
class Test
{
public:
	Test(int data, int count) :_data(data), _count(count)
	{}
	void Test1() const
	{}
	void Test2()
	{}
	void Test3() const
	{
		Test2();
		 _data;
		 _count=10;
	}
	void Test4()
	{
		Test1();
		_data;
		_count;
	}
public:
	const int _data;
	int _count;
};

int main()
{
	Test(4,7);
	system("pause");
	return 0;
}

以上代码说明了:普通成员函数可以使用const修饰的成员,也可以使用const修饰的成员函数。

带const的成员函数不可以使用普通成员函数和普通成员变量。

原因是:const修饰的是成员函数里的调用对象(this),而普通的成员函数和成员变量都需要this来指向。

const Test * const  this无法调用Test* const 

3.0 const修饰成员函数

(1)const修饰的成员函数不能修改任何的成员变量(mutable修饰的变量除外)。

(2)const成员函数不能调用非const成员函数,因为非const成员函数可以会修改成员变量

(3)const修饰函数的参数时不可以改变

看一个问题:

1. const对象可以调用非const成员函数和const成员函数吗?
2. 非const对象可以调用非const成员函数和const成员函数吗?

可以通过代码来验证

#include<iostream>
using namespace std;
class Test
{
public:
	Test(int data, int count) :_data(data), _count(count)
	{}
	void Test1() const
	{}
	void Test2()
	{}
public:
	const int _data;
	int _count;
};

int main()
{
	Test* t1;
	t1->Test1();//非const对象可以调用非const成员函数
	t1->Test2();//非const对象可以调用const成员函数
	const Test* t2;
	t2->Test1();//const对象可以调用const成员函数
	t2->Test2();//const对象不可以可以调用非const成员函数
	system("pause");
	return 0;
}


结果就说明了不能从const Test到this指针的类型(Test &)引用。

const对象不可以调用非const成员。

二:

volatile:本意是“易变的,直接存取原始内存地址,volatile影响编译器编译的结果,与volatile变量有关的运算,不要进行编译优化,以免出错

1.0      volatile对基本类型和对用户自定义类型的使用与const有区别,比如你可以把基本类型的变量赋值给volatile,但不能把用户自定义类型的变量赋值给volatile,而const都是可以的。

2.0 volatile成员函数

      关于类的话,首先如果类是volatile则里面的成员都是volatile的。其次要将成员函数声明为volatile则同const一样在函数最后声明即可。

#include<iostream>
using namespace std;
class Test
{
public:
	Test(int data, int count) :_data(data), _count(count)
	{}
	void Test1() volatile
	{}
	void Test2() volatile
	{}
public:
	const int _data;
	int _count;
};

int main()
{
	volatile Test t1(1,1);
	return 0;
}
不加也是可以的(在类成员函数后面)。


const和valatile的异同点:

1.0 一个变量可以同时是vonst和volatile

const总结:

const使用场景】
1、const修饰形参,一般和引用同时使用
2、const修饰返回值
3、const修饰类数据成员,必须在构造函数的初始化列表中初
始化
4、const修饰类成员函数,实际修饰隐含的this,表示在类中
不可以对类的任何成员进行修改
5、在const修饰的成员函数中要对类的某个数据成员进行修
改,该数据成员定义声明是必须加mutable关键字


猜你喜欢

转载自blog.csdn.net/WhiskyCocktail/article/details/78424839