C++ C++;可变成员函数
我是否需要将C++ C++;可变成员函数,c++,volatile,member-functions,C++,Volatile,Member Functions,我是否需要将x和y声明为volatile,或者将所有成员变量自动视为volatile 我想确保编译器不会将“使用x填充”重新排序为“使用y填充” 编辑: 如果我将普通类型转换为volatile类型,会发生什么?这是否会指示编译器不重新排序对该位置的访问?我想在特殊情况下,将一个普通变量传递给一个参数不稳定的函数。我必须确保编译器不会用前面或后面的读写操作对调用重新排序。标记成员函数volatile就像标记它const;这意味着接收方对象被视为声明为volatile T*。因此,对x或y的任何引用
x
和y
声明为volatile
,或者将所有成员变量自动视为volatile
我想确保编译器不会将“使用x
填充”重新排序为“使用y
填充”
编辑:
如果我将普通类型转换为
volatile
类型,会发生什么?这是否会指示编译器不重新排序对该位置的访问?我想在特殊情况下,将一个普通变量传递给一个参数不稳定的函数。我必须确保编译器不会用前面或后面的读写操作对调用重新排序。标记成员函数volatile
就像标记它const
;这意味着接收方对象被视为声明为volatile T*
。因此,对x
或y
的任何引用都将被视为在成员函数中读取的volatile
。此外,volatile
对象只能调用volatile
成员函数
也就是说,如果确实希望对它们的所有访问都被视为volatile
,那么您可能希望将x
和y
标记为volatile,如下代码:
class MyClass
{
int x, y;
void foo() volatile {
// do stuff with x
// do stuff with y
}
};
#包括
分类栏
{
公众:
无效试验();
};
福班
{
公众:
void test()volatile{x.test();}
私人:
条形图x;
};
int main()
{
富富,;
foo.test();
返回0;
}
使用gcc编译时引发错误:
#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;
}
main.cpp:在成员函数“void Foo::test()volatile”中:
main.cpp:14:33:错误:调用“Bar::test()volatile”时没有匹配的函数
main.cpp:7:8:注:候选项为:void Bar::test()
由于volatile
实例不能调用non-volatile
方法,因此我们可以假设,是的,x
和y
将在方法中volatile
,即使MyClass
的实例未声明volatile
注意:如果需要,可以使用
const_cast
删除volatile
限定符;但是要小心,因为就像const
一样,在某些情况下,这样做可能会导致未定义的行为。您不必显式声明成员变量
根据标准文件9.3.2.3
类似地,volatile语义(7.1.6.1)在访问对象及其非静态对象时应用于volatile成员函数
数据成员。
因此,使用原始示例:
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函数的语义不就是const函数的语义吗,因为你可以在非volatile对象上调用volatile函数,但是不是来自易失性对象的非易失性函数?@ereOn-在
g++
中的快速测试表明,您确实可以从-volatile
对象调用volatile
成员函数。volatile std::string
s没有用处的原因是,如果字符串本身是volatile
,它只能调用volatile
成员函数,而这些函数没有$标准的4.4.1阐明了可以将T*隐式转换为volatile T*,$9.3.1.3表示volatile
限定符会影响此
指针,这表明如果您有T
类型的对象,对于调用,T*
类型的this
指针可以转换为volatile T*
。@templatetypedef:我颠倒了逻辑(现在才7点;我还需要一些睡眠;)。谢谢,现在修好了。您可以从volatile
和非volatile
实例调用volatile
方法。但是如果您的实例是易失性的
,您将无法调用非易失性的
方法。@ereOn:所以,正如templatetypedef所说,它与常量的情况完全相同。相关部分当然不是g++,但标准:第4.4.1条似乎向我表明,将此从T*
隐式转换为volatile T*
是完全合法的。还请注意,9.3.2.4明确指出,如果调用cv限定函数的对象表达式是“作为cv限定的或cv限定的小于成员函数”,则可以调用cv限定函数在这个区域中,const
和volatile
之间没有区别。至于强制转换:如果原始对象实际上被定义为volatile,并且您将此对象或其一个成员作为左值(基本上,在赋值的左侧)作为非volatile对象访问,本标准第7.1.5.1.7条规定,程序行为未定义。不要这样做,即使它在当前测试数据上与当前编译器的当前版本一起工作。在AFAICS中,强制转换对于只读访问是合适的,就像对于const
.related一样
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
}
};