mutable(去除常性)
- 修饰普通变量,被mutable修饰的变量,将永远处于可变的状态,mutable在类中只能够修饰非静态数据成员
- 即使在一个const函数中,甚至结构体变量或者类对象为const,其mutable成员也可以被修改。
class Test //mutable
{
public:
int ma;
mutable int mb;
public:
Test() :ma(0),mb(0) { cout << "Test()" << endl; }
Test(int x=0,int y=0) :ma(x),mb(y) { cout << "Test(int ,int )" << endl; }
~Test() { cout << "~Test()" << endl; }
int GetMb()const
{
return mb+1;//加了const表明参数不能被修改
//但是mb前有mutable关键字 所以它在任何情况下都可以进行改变
}
int GetMa()const {
//return ma++ ; 错误 const不能修改
return ma;
}
};
int main() {
const Test t(20, 33);
//t.ma = 29; //const常对象 不能进行修改
t.mb = 66; //不会出错 mb定义前有mutable关键字 去除常性
cout << t.GetMb() << endl;
cout << t.GetMa() << endl;
}
explicit(阻止隐式转换)
- 阻止隐式转换的发生,声明为explicit的构造函数不能在隐式转换中使用。
- 隐式转换即是可以由单个实参来调用的构造函数定义了一个从形参类型到该类类型的隐式转换。编译器在试图编译某一条语句时,如果某一函数的参数类型不匹配,编译器就会尝试进行隐式转换,如果隐式转换后能正确编译,编译器就会继续执行编译过程, 否则报错。
class String {
public:
explicit String(int n) { cout << "String(int): " << this << endl; }
String(const char* c) { cout << "String(char): " << this << endl; }
~String() { cout << "~String(): " << this << endl; }
};
int main()
{
String s1 = "c"; //隐式调用String(const char *c) 在调用拷贝构造函数
//String s2 = 20; 不能做隐式int->String转换
String s3(30); //调用explicit String(int)
String s4 = String(99); //先调用explicit String(int) 在调用默认的拷贝构造函数
}
volatile(禁止代码优化)
-
作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次需要从内存中重新读取这变量的值。
-
变量如果加了 volatile 修饰,则会从内存重新装载内容,而不是直接从寄存器拷贝内容。
-
用volatile定义的变量会在程序外被改变,每次都必须从内存中读取,而不能重复使用放在cache或寄存器中的备份。