const volatile mutable constexpr

一、const

指针常量与常量指针

去掉const限定(类型退化)

const_cast

2. const在不同位置的作用

const int fun(); 函数返回值为 const

int fun(const int arg); 参数arg在函数内不可修改

int fun() const;函数为只读函数,这个函数不能访问所有this所能调用的内存,不能对类对象的数据成员(准确说是非静态数据成员)做任何改变

const和constexpr修饰指针
constexpr int x = 110;

int main()
{
	const int* p1 = nullptr;  			//p1是一个指向常量的指针,指针本身是变量
	constexpr int* p2 = nullptr;		//p2是一个指向变量的常量指针,指针本身是常量
	constexpr const int* p3 = nullptr;  //p3是一个指向常量的常量指针
	const int* const p4 = nullptr;      //p4是一个指向常量的常量指针
	
	p1 = &x;    // 正确,x是常量
	//*p1 = 2;  // 错误
	//p2 = &x;  // 错误
	*p2 = 2;    // 正确
	//p3 = &x;  // 错误   
	//*p3 = 2;  // 错误
	//p4 = &x;  // 错误
	//*p4 = 2;  // 错误

	return 0;
}

3. 常量(即const)对象

可以调用const成员函数,不能调用非const修饰的函数,非const对象既可以调用const成员函数,也可以调用非const成员函数

点击查看代码
#include <iostream>

class A
{
public:
	void Func1() const
	{
		std::cout << "func1\n";
	}
	void Func2()
	{
		std::cout << "func2\n";
	}
	const int Func3()
	{
		std::cout << "func3\n";
		return 1;
	}
	void Func4(const int n)
	{
		std::cout << "func4\n";
	}
};

int main()
{
	const auto a1 = A();
	auto a2 = A();

	a1.Func1();    // 正确
	//a1.Func2();  // 错误
	//a1.Func3();  // 错误
	//a1.Func4(0); // 错误

	a2.Func1();
	a2.Func2();
	a2.Func3();
	a2.Func4(0);
}

4. const用于重载

转载出处

点击查看代码
#include <iostream>

int f1(char* x)
{
	return 1;
}

int f1(const char* x)
{
	return 2;
}

int main()
{
	char s1[] = "aaa";
	const char s2[] = "bbb";

	std::cout << f1(s2) << std::endl;

	return 0;
}

二、volatile

转载自:详解C/C++中volatile关键字
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。

为了安全起见,只要是等待别的程序修改某个变量的话,就加上volatile关键字。

一般说来,volatile用在如下的几个地方:

  1. 中断服务程序中修改的供其它程序检测的变量需要加volatile;

  2. 多任务环境下各任务间共享的标志应该加volatile;

  3. 存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

三、mutable

四、constexpr

const expression 常量表达式

c++11规定:允许将变量声明为constexpr类型,以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化

一般来说,如果你认定变量是一个常量表达式,那就把它声明成constexpr类型。

constexpr int n1 = 20;     //20是常量表达式
constexpr int n2 = n1 + 1; //n1+1是常量表达式
constexpr int n3 = size(); //只有当`size()`是一个constexpr函数时才是一条正确语句

五、const和constexpr的区别

const表示的是变量只读,注意是变量,constexpr表示的是常量,在编译期就能确定值

点击查看代码
#include <iostream>
using namespace std;
int main()
{
    int a = 10;
    const int & con_b = a;
    cout << con_b << endl;
    a = 20;
    cout << con_b << endl; // 输出20,const修饰的con_b值被修改了
}

转载:C++11 constexpr和const的区别详解

五、检查类型是否为const或volatile限定,添加、移除const或volatile限定

    const int ic = 0;
    volatile int iv = 0;
    std::cout << std::is_const< decltype(ic)>::value;//1
    std::cout << std::is_const<int>::value;//0
    std::cout << std::is_const<const int*>::value;//0
    std::cout << std::is_const<int* const>::value;//1
    std::cout << std::is_volatile<decltype(iv)>::value;//1
    std::cout << std::is_volatile<int>::value;// 0
    std::is_const<const int>::value_type Bool;//Bool是一个没有初始化的bool型变量
    std::is_const<const int>::type;
    std::remove_const<const int>::type Int;//Int是一个没有初始化的int型变量
    std::remove_cv<const volatile int>::type CV;//CV是一个没有初始化的int型变量

    int i = 0;
    auto&& ret1 = std::as_const<int>(i);//类型为const int&
    auto&& ret2 = std::as_const(i);//类型为const int&
    auto ret3 = std::as_const(i);  //类型为int

    std::add_const<int>::type CI = 0;  //CI是一个const int型且初始值为0的常量(const必须初始化)
posted @ 2020-12-04 23:07  滴哒哒哒  阅读(9)  评论(0编辑  收藏  举报