【C++】 const static volatile

一、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就是为了防止这种情况发生。

上一篇:2.深入浅出java多线程


下一篇:volatile