为什么const_cast远离volatile只能用于指针

Che*_*eng 2 c++ pointers volatile const-cast

// OK!
volatile CString* a0;
CString* a1 = const_cast<CString *>(a0);

// error C2440: 'const_cast' : cannot convert from 'volatile CString' to 'CString'
volatile CString b0;
CString b1 = const_cast<CString>(b0);
Run Code Online (Sandbox Code Playgroud)

我在想,为什么const_cast只为指针工作?如何编译第二个案例?

Mik*_*our 9

const_cast作用于指针和引用,删除constvolatile限定符.使用它来转换为对象类型是没有意义的,因为那样你就可以创建一个副本,无论如何都不需要与原始版本具有相同的cv限定符.

如果您转换为非易失性引用,您的第二个示例将编译:

volatile CString b0;
CString & b1 = const_cast<CString &>(b0);
Run Code Online (Sandbox Code Playgroud)

但是,使用该引用会给出未定义的行为,因为底层对象本身就是如此volatile.const_cast当您知道基础对象不具备这些资格时(或者在删除时const,当您知道结果不会用于修改对象时)时,您应该仅用于删除资格.

如果对象允许复制易失性对象(可能是复制构造函数采用参考易失性或易失性限定函数或转换运算符),则只能获得副本.如果CString不提供任何这些,则无法安全地复制volatile该类型的对象.

  • @ 6502:C++ 11 7.1.6.1/6说"如果通过使用具有非易失性限定类型的glvalue来尝试引用使用volatile限定类型定义的对象,则程序行为是未定义".`volatile`与线程无关,除了在一些非标准扩展的编译器中,它也意味着"原子".它将对象的访问定义为程序的可见副作用; 删除资格可以改变这些副作用,因此以不确定的方式改变程序的行为. (2认同)
  • 故事的寓意是,编写类的人通常会努力确保该类的`const`实例做一些合理的事情,提供`const`版本的非变异成员函数,并通过`const MyClass& `在适当的地方.他们很少为`volatile`实例做类似的事情.您可能会发现,对于许多类的`volatile`实例,您唯一可以做的就是销毁它,包括标准类. (2认同)