aJ.*_*aJ. 10 c++ const volatile
我正在阅读有关volatile成员函数的信息并且遇到了一个肯定,即成员函数可以同时是const和volatile.我没有真正使用这样的东西.任何人都可以分享他们在成员函数作为const和volatile一起实际使用的经验.
我写了小班来测试同样的东西:
class Temp
{
public:
Temp(int x) : X(x)
{
}
int getX() const volatile
{
return X;
}
int getBiggerX()
{
return X + 10;
}
private:
int X;
};
void test( const volatile Temp& aTemp)
{
int x = aTemp.getX();
}
int main(int argc, char* argv[])
{
const volatile Temp aTemp(10);
test(aTemp);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
dir*_*tly 17
该CV资格蒸馏方式:
我不会改变价值,但有一些东西可以.
您正在向自己承诺,您不会更改值(const限定条件)并要求编译器保持其对象的粘性,并关闭所有优化(volatile限定).不幸的是,在volatile公平处理方面,编译器供应商几乎没有标准.而且volatile是一个暗示之后所有的编译器.
实际用例是系统时钟.假设0xDEADBEEF是您编写的硬件时钟寄存器的系统特定地址:
int const volatile *c = reinterpret_cast<int *>(0xDEADBEEF);
Run Code Online (Sandbox Code Playgroud)
您无法修改该寄存器值,但每次读取它时,它可能具有不同的值.
此外,可以使用它来模拟UART.
Joh*_*itb 13
您询问了volatile成员函数的实际示例.好吧,我想不到一个,因为我能想象的唯一情况是如此低级,我不会考虑首先使用成员函数,而只是一个简单的结构,数据成员通过易失性引用访问.
但是,为了回答这个问题,让我们将const volatile函数放入其中.假设您有一个地址为0x378h的端口,其中包含2个整数,每个4个字节.然后你可以写
struct ints {
int first;
int second;
int getfirst() const volatile {
return first;
}
int getsecond() const volatile {
return second;
}
// note that you could also overload on volatile-ness, just like
// with const-ness
};
// could also be mapped by the linker.
ints const volatile &p = *reinterpret_cast<ints*>(0x378L);
Run Code Online (Sandbox Code Playgroud)
你在说
我没有改变它们,但是这个抽象语义之外的另一个东西可能会改变它.所以总是从它的地址做一个真正的负载.
实际上,volatile表示对象的值可能不是最后存储在其中的值,但实际上是未知的,并且可能在外部(编译器无法观察)条件之间进行了更改.因此,当您从易失性对象中读取时,编译器必须模拟确切的抽象语义,并且不执行任何优化:
a = 4;
a *= 2;
// can't be optimized to a = 8; if a is volatile because the abstract
// semantics described by the language contain two assignments and one load.
Run Code Online (Sandbox Code Playgroud)
以下内容已经确定了什么volatile.一切都可以1.9在标准中找到.它所讨论的参数是实现定义的东西,比如某种类型的sizeof.
本国际标准中的语义描述定义了参数化的非确定性抽象机器.本国际标准对符合实施的结构没有要求.特别是,它们不需要复制或模拟抽象机器的结构.相反,需要符合实现来模拟(仅)抽象机器的可观察行为,如下所述.[...]
执行格式良好的程序的一致实现应该产生与具有相同程序和相同输入的抽象机的相应实例的可能执行序列之一相同的可观察行为.[...]
抽象机器的可观察行为是它对易失性数据的读写顺序以及对库I/O函数的调用.