一、Const
1、C中定义常量const
const 修饰的变量在使用时在内存只有一份拷贝。
Code
const int a = 5; // a不可变
const int *p = &a;
int *p = &a;//Error
/*看const在*前还是*后*/
const char *ptr; //*ptr不可变,即ptr所指向的内容不可变
char * const ptr;//ptr不可变
const char *const ptr;//ptr以及ptr指向的内容都不可变
/*函数传参*/
void Fun(const char *ptr){} //保证传过来的内容在函数内不发生改变,如果是类对象,返回值一般不设置为const,const修饰的类对象只能访问const成员函数
2、C++类相关const
C++中,有const修饰的类对象,类成员变量,类成员函数。const修饰的类成员变量只能在构造函数的初始化列表进行初始化。mutable修饰的成员变量在const修饰的成员函数中可以进行修改。
(1)const对象可以调用非const成员函数吗?
(2)非const对象可以调用const成员函数吗?
(3)const成员函数内可以调用其它的非const成员函数吗?
(4)非const成员函数内可以调用其它的const成员函数吗?
对象类型 | 普通成员函数 | const修饰的成员函数 |
---|---|---|
普通对象 | √ | √ |
const修饰的对象 | × | √ |
const修饰的成员函数 | × | √ |
Code
class Fun{
public:
Fun():a(0){} //含有const成员的构造函数必须对const进行初始化所以设置
virtual ~Fun(){}
Fun(int aa):a(aa){}
void FunA() const{
//const成员函数,等价于 void FunA(const Fun this){}
}
void FunB(){}
protected:
private:
const int a;
}
int main()
{
Fun t(10);
Fun &a = t;
a.FunA(); //可以
a.FunB();//可以
const Fun &b = t;
b.FunA();//可以
//b.FunB();//不可以,因为传入的const Fun &this ,而默认是 Fun &,
return 0;
}
二、Static
static 特点:
1、静态随着类的加载而加载
2、静态优先于对象存在
3、类创建的所有对象都可以访问这个静态成员
4、可以通过对象调用,也可以通过类名调用
5、static方法中没有this
6、同一个类中静态方法,只能访问静态成员变量,只能访问静态方法。
c/c++共有
1):修饰全局变量时,表明一个全局变量只对定义在同一文件中的函数可见。
2):修饰局部变量时,表明该变量的值不会因为函数终止而丢失。
3):修饰函数时,表明该函数只在同一文件中调用。
c++独有:
4):修饰类的数据成员,表明对该类所有对象这个数据成员都只有一个实例。即该实例归所有对象共有。
5):用static修饰类成员函数归整个类所有。这意味着一个静态成员函数只能访问它的参数、类的静态数据成员和全局变量。
注意:
- 静态常量数据成员可以在类内初始化(即类内声明的同时初始化),也可以在类外,即类的实现文件中初始化,不能在构造函数中初始化,也不能在构造函数的初始化列表中初始化;
- 静态非常量数据成员只能在类外,即类的实现文件中初始化,也不能在构造函数中初始化,不能在构造函数的初始化列表中初始化;
- 非静态的常量数据成员不能在类内初始化,也不能在构造函数中初始化,而只能且必须在构造函数的初始化列表中初始化;
- 非静态的非常量数据成员不能在类内初始化,可以在构造函数中初始化,也可以在构造函数的初始化列表中初始化;
Code静态成员变量的初始化
class A{
static int n;
#if 0
static int n = 0;//Error,static 只能有一次初始化,所以不能在类中,也不能在构造函数中,只能在类外初始化一次。
#endif
static const int m = 0; // True 静态常量可以在类中初始化,因为静态保证了只有一份,而const保证了只初始化一次,所以可以。
}
A::n = 0;
三、volatile
volatile 用于防止读脏数据,让每次进程在使用该变量时都从内存中重新读值。例如,线程A和线程B都使用一个变量i,此时线程B使用处理器时保存的现场中i的值是1,CPU调度此时A占用CPU,A的现场中此时i的值是1,但是此时A将i的值+1,此时i的值是2,A时间片轮完,B进入CPU,还原现场,此时现场里寄存器的值仍然是1,volatile就是为了防止这种情况发生。