C++中的易失成员函数与常量成员函数

5

很多人认为"volatile成员函数的工作方式与const完全类似"。

它们在某种意义上是相似的,如果一个指针被标记为const/volatile,则只能访问被标记为const/volatile的成员函数。

但实际上将成员函数定义为const会产生附加效果,使该函数变为只读。在函数内部对对象进行任何修改都会导致编译错误。在volatile成员函数中是否存在这样的类比?


这个链接可能会有所帮助。https://dev59.com/zm435IYBdhLWcg3w-lP2 - Abhishek Bansal
3个回答

3

一个成员函数被声明为volatile会使得对象的成员变量也变成volatile,即this会像被定义为volatile T * const this一样。因此,对任何成员变量的引用都将是volatile的。

请记住,volatile读/写操作是编译器无法省略/重新排序的操作。它们通常用于实现映射到内存的硬件设备或类似功能的东西。

老实说,我从来没有使用过这个特性,除了做一些巧妙的技巧来过滤对函数的访问,而不是利用对象的volatile。如果你的代码足够底层需要使用volatile,那么你可能只需要在需要的变量上放置volatile


注意:虽然编译器不能重新排序volatile变量上的操作,但缺乏内存屏障意味着乱序处理器可能会在其执行管道中重新排序它们,并且访问相同数据的另一个处理器可能无法按照完成顺序看到更改(简而言之:这真的是硬件特定的,对于多线程没有帮助)。 - Matthieu M.
@MatthieuM.:没错,这就是为什么我故意没有谈论线程或共享内存。无论如何,在SO上有很多关于volatile变量语义的问题,但关于volatile成员函数的含义却不是很多。 - rodrigo

0

简短回答:是的。

如果一个对象的实例被声明为volatile,那么调用它的非volatile方法是错误的(或者对于那些方法来说,调用其他非volatile方法也是错误的)。

一个非volatile实例仍然可以调用volatile方法,但请注意,在类中有两个完全相同的方法 - 一个是volatile的,另一个不是,这是完全合法的。在这种情况下,非volatile实例将调用非volatile版本的方法。


0
实际上,将成员函数定义为const还有一个额外的效果,使得该函数只读。但这有点误解了。它并不会使成员函数只读 - 它使*this const。两者之间有一个小但重要的区别(成员函数仍然可以修改mutable成员,如果它想捣乱,它可以强制转换掉*this的const属性来修改任何它想要的东西,而编译器不会抱怨)。而且,volatile成员函数的工作方式与此完全相同 - 它使*this volatile。

“它防止非const的this调用成员函数。”但是,仅仅定义const方法就会导致编译器错误。在函数内部修改对象的任何内容都会导致编译器错误。这难道不意味着编译器将该函数视为“只读”吗? - Alex
@Alex:编译器错误是因为thisconst(这是调用成员函数的前提条件)。但是,成员函数仍然可以修改mutable成员,如果它想恶意行事,它可以强制转换thisconst性质以修改任何想要修改的内容,而编译器不会抱怨。 - Sander De Dycker
"它防止非const的成员函数被调用,以保证this指针是const类型。反之则不行,如果方法不是const,则无法为const this调用该方法。" - hyde
@hyde:哦,我的天啊 - 可能还没醒呢。 - Sander De Dycker

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