[C++] 关键字 mutable 和 volatile

mutable

mutable 意思是“易变的”。
const 类型对象的mutable域可以修改, 如果通过const指针或引用访问对象,mutable域也可以修改。简而言之,使用mutable关键字将覆盖任何封闭的const语句,编译器会因为此关键字不会将对象存储于只读内存中。
(A mutable field can be changed even in an object accessed through a const pointer or reference, or in a const object, so the compiler knows not to stash it in R/O memory. )

mutableconst进行交互。 如果你有一个const指针,你通常不能改变成员。 mutable为该规则提供了一个例外。

volatile

volatile意思也是“易变的”。
关键字volatile依赖于实现,声明变量时使用,将阻止编译器优化这些变量。如果变量的值会出其不意地被修改(例如中断, 或者一些内核级驱动),而编译器根本不知道, 这样的修改会与编译器可能会执行的优化行为相冲突,volatile的作用就是告诉编译器不要进行优化。例如:x = 1; x = 0;如果x声明为volatile, 那么即使编译器将执行两条写操作(在硬件级别可能非常重要), 如果没有volatile, 编译器有可能不会执行写1操作,毕竟 1从来没用到。声明为 volatile 变量的修改不受程序控制,编译器不得将这些变量内容存在寄存器中,必须每次读或写内存地址。

比如说你在控制LED灯的状态, 写0设为OFF,写1设为ON。如果想用LED显示一些错误状态,可是编译器自行决定优化所有的写操作,只保留最后一条,毕竟前面的若干值全都没有使用,那么LED不会闪烁,期望的行为不会实现。

测试 mutable

class Transformation
{
    private:
        vec3 translation;
        vec3 scale;
        vec4 rotation;
        mutable mat4 transformation;
        mutable bool changed;
    public:
        Node()
        {
            [...]
            changed = false;
        }
        void set_translation(vec3 _translation)
        {
            translation = _translation;
            changed = true;
        }
        void set_scale(...) ...
        mat4 get_transformation() const
        {
            if(changed)
            {
                 // transformation and changed need to be mutable here
                 // This take a long time...
                 transformation = f(translation, scale, rotation); 
                 changed = false;
            }
            return transformation;
        }
};
void apply_tranformation(const Transformation* transfo)
{
    apply(transfo->get_transformation());
}

我自己写的测试代码:

class TestMutable {
private:
    mutable int count;
public:
    TestMutable(int n) : count(n) {}
    void printValue() const
    { 
        // 如果前面没有加 mutable, 这一行编译会显示:
        // 由于正在通过常量对象访问count, 因此无法对其修改。
        count++;  
        cout << count << endl;
    } 
};

int _tmain(int argc, char* argv[])
{
    const TestMutable obj(0);
    obj.printValue();
    system("pause");
    return 0;
}

编译通过,输出1.

来自于stackoverflow的答案。


[1] https://stackoverflow.com/questions/2444695/volatile-vs-mutable-in-c/2444705
[2] https://stackoverflow.com/questions/4554031/when-have-you-used-c-mutable-keyword

猜你喜欢

转载自blog.csdn.net/ftell/article/details/80475955