C++ 易失性成员函数
Posted
技术标签:
【中文标题】C++ 易失性成员函数【英文标题】:C++ volatile member functions 【发布时间】:2011-06-17 03:17:55 【问题描述】:class MyClass
int x, y;
void foo() volatile
// do stuff with x
// do stuff with y
;
我需要将x
和y
声明为volatile
还是将所有成员变量自动视为volatile
?
我想确保编译器不会将“带有x
的东西”重新排序为“带有y
的东西”。
编辑:
如果我将普通类型转换为 volatile
类型会发生什么?这会指示编译器不要重新排序对该位置的访问吗?我想在特殊情况下将普通变量传递给参数为 volatile 的函数。我必须确保编译器不会通过之前或之后的读写重新排序该调用。
【问题讨论】:
相关***.com/questions/2444734/… 【参考方案1】:标记一个成员函数volatile
就像标记它const
;这意味着接收者对象被视为被声明为volatile T*
。因此,任何对x
或y
的引用都将被视为在成员函数中读取volatile
。而且volatile
对象只能调用volatile
成员函数。
也就是说,如果您确实希望所有对它们的访问都被视为volatile
,那么您可能需要标记x
和y
volatile
。
【讨论】:
【参考方案2】:您不必显式声明成员变量..
来自标准文档9.3.2.3,
类似地,volatile 语义 (7.1.6.1) 在访问对象及其非静态时应用于 volatile 成员函数 数据成员。
【讨论】:
【参考方案3】:以下代码:
#include <iostream>
class Bar
public:
void test();
;
class Foo
public:
void test() volatile x.test();
private:
Bar x;
;
int main()
Foo foo;
foo.test();
return 0;
使用 gcc 编译时引发错误:
main.cpp: In member function 'void Foo::test() volatile':
main.cpp:14:33: error: no matching function for call to 'Bar::test() volatile'
main.cpp:7:8: note: candidate is: void Bar::test() <near match>
由于volatile
实例不能调用non-volatile
方法,我们可以假设,是的,x
和y
在方法中将是volatile
,即使@987654328 的实例@ 未声明 volatile
。
注意:如果需要,您可以使用 const_cast<>
删除 volatile
限定符;但是要小心,因为就像const
一样,在某些情况下这样做会导致未定义的行为。
【讨论】:
如果我对此有误,请纠正我,但 volatile 函数的语义不像 const 函数那样,因为您可以在非易失性对象上调用 volatile 函数,但不能调用非易失性函数来自 volatile 对象? @ereOn- 在g++
中的快速测试表明您确实可以从 on-volatile
对象调用volatile
成员函数。 volatile std::string
s之所以没用,是因为如果字符串本身是volatile
,则只能调用volatile
的成员函数,其中没有。标准的 $4.4.1 阐明了您可以将 T* 隐式转换为 volatile T*,并且 $9.3.1.3 表示 volatile
限定符会影响 this
指针,这表明如果您有一个类型为 @987654341 的对象@,T*
类型的 this
指针可以转换为 volatile T*
用于调用。
@templatetypedef:我颠倒了逻辑(现在才早上 7 点;我还需要睡觉;))。谢谢,现在已经修好了。您可以从volatile
和non-volatile
实例调用volatile
方法。但是,如果您的实例是 volatile
,您将无法调用 non-volatile
方法。
@ereOn:所以,正如 templatetypedef 所说,它与 const
完全相同。相关部分当然不是 g++,但标准:第 4.4.1 条似乎向我表明,this
从T*
到volatile T*
的必要隐式转换是完全合法的。另请注意,9.3.2.4 明确指出,如果您调用它的对象表达式“与成员函数一样 cv 限定或更少 cv 限定”,则可以调用 cv 限定函数。在这方面const
和volatile
没有区别。
至于转换:如果原始对象实际上被定义为 volatile,并且您将这个对象或其成员之一作为左值(基本上,在赋值的左侧)作为非volatile,标准的第 7.1.5.1.7 条表示程序行为未定义。不要这样做,即使它在当前测试数据上与当前编译器的当前版本一起使用。 AFAICS,演员表对于只读访问来说是可以的,就像const
一样。【参考方案4】:
所以使用原来的例子:
class MyClass
int x, y;
void foo() volatile
// do stuff with x
// do stuff with y
// with no "non-volatile" optimization of the stuff done with x, y (or anything else)
void foo()
// do stuff with x
// do stuff with y
// the stuff done with x, y (and anything else) may be optimized
;
【讨论】:
以上是关于C++ 易失性成员函数的主要内容,如果未能解决你的问题,请参考以下文章