explicit
用法
禁止隐式生成临时对象
测试用例
1、不加explicit时,运行通过,因为test = 60;
该行,编译器会认为它隐式生成临时对象,所以运行成功,即编译自行推演处理。但是它是不可控的。
加上explicit后,程序就会报错。错误提示如下:
class Test
{
public:
explicit Test(int a)
:ma(a)
{}
private :
int ma;
};
int main()
{
Test test(20);
test = 60;//
return 0;
}
volatile
用法
禁止代码优化
测试用例
int a=10;
这一行的汇编语言是 mov dword ptr[a], 0Ah
也就是将数据10放在a的地址下。
而b = a;
、c = a;
、d = a;
这三条语句的汇编语言均为mov eax, dword ptr[a]; mov dword ptr[b], eax;
意为将a的值存放在寄存器eax中,再将eax的值存放在b中。
不加volatile
时,编译器会进行代码优化,只在b = a;
进行一次将a的值存放在寄存器eax中,后面两句直接进行赋值操作。
但是在多线程的情况下,代码优化是不可取的,因为会有多个线程对变量进行操作。
所以可以在int a=10;
前加上volatile
class Test
{
public:
Test(int a)
:ma(a)
{}
private :
int ma;
};
int main()
{
int a=10;// mov dword ptr[a], 0Ah
int b,c,d;
b = a;//mov eax, dword ptr[a]; mov dword ptr[b], eax;
c = a;//mov eax, dword ptr[a]; mov dword ptr[b], eax;
d = a;//mov eax, dword ptr[a]; mov dword ptr[b], eax;
return 0;
}
- volatile关键字修饰变量的情况:
1.设备的硬件寄存器(如:状态寄存器),即对硬件寄存器进行操作
2.一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3.多线程应用中被几个任务共享的变量
mutable
用法
去除常性
测试用例
在Test test(10, 20);
前加上const
后,表示常对象,特点是成员变量不允许修改。所以在进行test.ma = 100;
test.mb = 20;
这两句时,程序出错,运行结果如下
如果给Test类中的成员变量int ma;
和int mb;
中前面都加上mutable
,则运行成功。
class Test
{
public:
Test(int a, int b)
:ma(a), mb(b)
{}
public:
int ma;
int mb;
};
int main()
{
const Test test(10, 20);
test.ma = 100;
test.mb = 20;
return 0;
}