成员函数被声明为volatile是什么意思?

10

通常情况下,我看到使用 const 限定符表示一个常量成员函数。但是当使用 volatile 关键字时,它表示什么意思呢?

void f() volatile {}

这对我来说编译得很好,但我不明白这是干什么用的。在我的搜索中找不到关于此事的任何信息,所以如果有任何帮助,将不胜感激。

更新:为了明确起见,我知道volatile的用法。我只是不知道它在这种情况下意味着什么。

3个回答

15

volatile限定符在成员函数中类似于const限定符。它允许在volatile对象上调用该成员函数:

struct A {
    void f() volatile {}
    void g() {}
};

int main() {
    A volatile a;
    a.f(); // Allowed
    a.g(); // Doesn't compile
}

2
volatile对象是什么意思?[可以改变吗?] - Dineshkumar
2
volatile 表示该值可能被编译器未知的事物(如内存映射硬件)访问,并禁用某些优化。访问 volatile 值被视为 as-if 规则目的下的副作用。 - Mankarse
但是,如果我们将成员函数视为获取'A * this'隐式参数,则对象不会“按定义”对成员函数易失性吗? - einpoklum
@einpoklum 我不明白你的逻辑。A* this没有cv限定符,所以它为什么会是指向易变量的“定义”呢? - Mankarse
因为你不知道指针指向什么。它可能指向一个易失变量。你不能假设它不会这样。 - einpoklum
@einpoklum:你知道它指向什么。如果A没有被标记为volatile,那么指针就不能指向一个volatile变量。(这是由类型系统禁止的,如果你使用const_cast绕过这个限制,会导致未定义行为)。只有在成员函数上加上volatile修饰符,类型系统才会允许这样做。对于const也是同样的道理。 - Mankarse

10

在成员函数中,constvolatile限定符应用于*this。在该成员函数内对任何实例成员的访问都将是volatile访问,具有任何volatile变量的语义。特别地,无法在volatile对象上调用非volatile成员函数,并且volatileconst一样适用于重载:

#include <iostream>

class C {
public:

    void f() {
        std::cout << "f()\n";
    }

    void f() const {
        std::cout << "f() const\n";
    }

    void f() volatile {
        std::cout << "f() volatile\n";
    }

    void f() const volatile {
        std::cout << "f() const volatile\n";
    }

};

int main() {

    C c1;
    c1.f();

    const C c2;
    c2.f();

    volatile C c3;
    c3.f();

    const volatile C c4;
    c4.f();

}

编译器显示c2和c4未初始化的常量错误? - Dineshkumar
@Dineshkumar:不应该出现这种情况。你使用的是哪个编译器? - Jon Purdy
@Dineshkumar:是哪个版本?在ideone上,我可以使用GCC 4.3.2重现您的错误,但不能使用4.7.2,因此我认为这是编译器的错误。该对象由隐式默认构造函数初始化。 - Jon Purdy
当我添加了一个构造函数时,它就正常工作了。为什么会这样呢? - Dineshkumar
2
@Dineshkumar:实际上这是一个标准中的错误,已在C++11中修复,并相应地在GCC 4.6中进行了更改。 - Jon Purdy
显示剩余2条评论

2

被声明为volatile的对象未参与某些优化,因为它们的值可以随时更改。系统总是在请求点读取volatile对象的当前值,即使先前的指令要求从同一对象读取值。此外,对象的值在分配时会立即写入。

只有volatile成员函数才能调用volatile对象。

因此,将成员函数标记为volatile会使该成员函数内对对象的非静态数据成员的任何访问都视为volatile。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接