cv(constvolatile)类型限定符

来自cppreference.com
< cpp‎ | language

出现于任意类型指定符中,包括声明文法decl-specifier-seq ,以指定被声明对象或被命名类型的常性或易变性。

  • const ——定义类型为
  • volatile ——定义类型为易变
  • mutable ——应用于非引用非 const 类型的非静态类成员,并指定该成员不影响类的外部可见状态(常用于互斥、内存缓存、惰性求值、及访问设备)。 const 类实例的 mutable 成员是可修改的。(注意: C++ 语言文法将 mutable 当做 storage-class-specifier (存储类指定符),但它不影响存储类。)

目录

[编辑] 解释

对于任何函数类型引用类型以外的类型 T (包括不完整类型), C++ 类型系统中有另外三种相异的类型: const-qualified Tvolatile-qualified Tconst-volatile-qualified T

注意:数组类型被当做与其元素类型有相同的 cv 限定。

最初创建对象时,所用的 cv 限定符(可以是声明decl-specifier-seqdeclarator 的一部分,或 new 表达式type-id 的一部分)确定对象的常性或易变性,如下所示:

  • const 对象——类型为 const-qualified 的对象,或 const 对象的非 mutable 子对象。这种对象不能修改:尝试直接这么做是编译时错误,且尝试间接这么做(例如通过到非 const 类型的引用或指针修改 const 对象)导致未定义行为。
  • volatile 对象——类型为 volatile-qualified 的对象,或 volatile 对象的子对象,或 const volatile 对象的 mutable 子对象。通过 volatile 限定类型泛左值表达式的每次访问(读或写操作、成员函数调用等)都被当作对于优化目的的可见副效应(即在执行的单一线程内, volatile 访问不能被优化掉或者与另一先序或后序于该 volatile 访问的可见副效应重排序。这使得 volatile 对象适用于与信号处理函数的交流,但不适于与另一执行线程交流,参阅 std::memory_order )。尝试通过非 volatile 泛左值引用 volatile 对象(例如,通过到非 volatile 类型的引用或指针)导致未定义行为。
  • const volatile 对象——类型为 const-volatile-qualified 的对象, const volatile 对象的非 mutable 子对象, volatile 对象的 const 子对象,或非 mutable 对象的 const 子对象。表现同 const 对象与 volatile 对象两者。

存在以增加限制排序的 cv 限定符偏序。从而类型可以说有更多更少 cv 限定:

  • 非限定 < const
  • 非限定 < volatile
  • 非限定 < const volatile
  • const < const volatile
  • volatile < const volatile

到 cv 限定类型的引用和指针能被隐式转换更加 cv 限定类型的引用和指针。特别是允许下列转换:

  • 非限定类型的引用/指针能被转换成到 const 的引用/指针
  • 非限定类型的引用/指针能被转换成到 volatile 的引用/指针
  • 非限定类型的引用/指针能被转换成到 const volatile 的引用/指针
  • const 类型的引用/指针能被转换成到 const volatile 的引用/指针
  • volatile 类型的引用/指针能被转换成到 const volatile 的引用/指针
注意:多级指针另有附加限制

欲转换到 cv 限定类型的引用或指针为到更少 cv 限定类型的引用或指针,必须使用 const_cast

[编辑] 关键词

const, volatile, mutable

[编辑] 示例

int main()
{
    int n1 = 0;           // 非 const 对象
    const int n2 = 0;     // const 对象
    int const n3 = 0;     // const 对象(同 n2 )
    volatile int n4 = 0;  // volatile 对象
    const struct
    {
        int n1;
        mutable int n2;
    } x = {0, 0};      // 带 mutable 成员的 const 对象
 
    n1 = 1; // ok ,可修改对象
//  n2 = 2; // 错误:不可修改对象
    n4 = 3; // ok ,当做副效应
//  x.n1 = 4; // 错误: const 对象的成员为 const
    x.n2 = 4; // ok , const 对象的 mutable 成员不是 const
 
    const int& r1 = n1; // 绑定到非 const 对象的 const 引用
//  r1 = 2; // 错误:试图通过到 const 的引用修改
    const_cast<int&>(r1) = 2; // ok ,修改非 const 对象 n1
 
    const int& r2 = n2; // 绑定到 const 对象的 const 引用
//  r2 = 2; // 错误:试图通过到 const 的引用修改
//  const_cast<int&>(r2) = 2; // 未定义行为:试图修改 const 对象 n2
}

输出:

# x86_64 平台上生成的典型机器码
# (只输出贡献可观测副效应的代码)
main:
    movl    $0, -4(%rsp) # volatile int n4 = 0;
    movl    $3, -4(%rsp) # n4 = 3;
    xorl    %eax, %eax   # return 0 (隐式)
    ret

[编辑] 参阅

const 限定符C 文档
volatile 限定符C 文档