直接处理硬件的程序常常包含这样的数据元素,它们的值由程序直接控制之外的过程控制。例如,程序可能包含一个由系统时钟定时更新的变量。当对象的值可能在程序的控制或检测之外被改变时,应该将该对象声明为volatile。关键字volatile告诉编译器不应对这样的对象进行优化。
    用法类似const,我们可以按顶层const、底层const去理解volatile。

    1. volatile int display_register; // 该int值可能发生改变
    2. volatile Task *curr_task; // curr_task指向一个volatile对象
    3. volatile int iax[max_size]; // iax的每个元素都是volatile
    4. volatile Screen bitmapBuf; // bitmapBuf的每个成员都是volatile
    5. volatile int v; // v是一个volatile int
    6. int *volatile vip; // vip是一个volatile指针,它指向int
    7. volatile int *ivp; // ivp是一个指针,它指向一个volatile int
    8. volatile int *volatile vivp; // vivp是一个volatile指针,它指向一个volatile int
    9. int *ip = &v; // 错误:必须使用指向volatile的指针
    10. ivp = &v; // 正确:ivp是一个指向volatile的指针
    11. vivp = &v; // 正确:vivp是一个指向volatile的volatile指针

    合成的拷贝对volatile对象无效,这是和const的区别。不能使用合成的拷贝/移动构造函数及赋值运算符初始化volatile对象或从volatile对象赋值。
    如果一个类希望拷贝、移动或赋值它的volatile对象,则该类必须自定义拷贝或移动操作。

    1. class Foo {
    2. public:
    3. Foo(const volatile Foo&); //从一个volatile对象进行拷贝
    4. // 将一个volatile对象赋值给一个非volatile对象
    5. Foo& operator=(volatile const Foo&);
    6. // 将一个volatile对象赋值给一个volatile对象
    7. Foo& operator=(volatile const Foo&) volatile;
    8. // Foo类的剩余部分
    9. }