【问题标题】:What are top-level const qualifiers?什么是顶级 const 限定符?
【发布时间】:2011-12-16 09:34:32
【问题描述】:

“顶级”限定符中的const 在 C++ 中是什么意思?

还有什么其他级别?

例如:

int const *i;
int *const i;
int const *const i;

【问题讨论】:

标签: c++ constants


【解决方案1】:

两个级别的 const 是: * 低级常量 * 顶级常量

您应该通过引用和指针查看顶级和低级 const,因为这是它们相关的地方。

int i = 0;
int *p = &i;
int *const cp = &i;
const int *pc = &i;
const int *const cpc = &i;

在上面的代码中,有 4 种不同的指针声明。让我们逐一介绍,

int *p普通指针可用于对底层对象进行更改并可以重新分配。

int *const cp(顶级常量):常量指针可用于对底层对象进行更改,但不能重新分配。 (不能将其更改为指向另一个对象。)

const int *pc(低级 const):指向 Const 的指针不能用于更改底层对象,但它本身可以重新分配。

const int *const cpc(顶级和低级 const):Const Pointer to a Const 既不能用于更改底层对象,也不能重新分配自身。

此外,顶级 const 在分配给另一个对象时总是被忽略,而低级 const 不会被忽略。

int i = 0;
const int *pc = &i;
int *const cp = &i;

int *p1 = cp; // allowed
int *p2 = pc; // error, pc has type const int*

希望这有帮助:) 仅供参考:C++ Primer 有很多相同的信息!!!

【讨论】:

  • 非常感谢,这是最清楚的解释。顺便说一下,C++ Primer 是引导我到这里的书。
【解决方案2】:

顶级 const 限定符会影响对象本身。其他只是 与指针和引用相关。他们不做对象 const,并且仅防止使用指针或通过路径修改 参考。因此:

char x;
char const* p = &x;

这不是顶级常量,并且没有一个对象是不可变的。 表达式*p不能用来修改x,但其他表达式 可; x 不是常量。就此而言

*const_cast<char*>( p ) = 't'

合法且定义明确。

但是

char const x = 't';
char const* p = &x;

这一次,x 上有一个顶级 const,所以x 是不可变的。不 允许更改它的表达式(即使使用了const_cast)。这 编译器可能会将x 放在只读内存中,并且它可能会假设 x 的值永远不会改变,无论其他代码可能做什么。

要给指针顶级const,你会写:

char x = 't';
char *const p = &x;

在这种情况下,p 将永远指向x;任何改变这一点的尝试 是未定义的行为(编译器可能会将p 放入只读内存中, 或假设*p 引用x,而不管其他任何代码)。

【讨论】:

  • 还有一点:在编写函数时,参数的顶级限定符被丢弃。这意味着void foo(char const)void foo(char) 是相同的功能(实际上它们可以互换)。推理是,由于参数是由副本获取的,调用者并不关心副本是否可以修改,因此对她来说是透明的。
  • @MatthieuM。好点,虽然不完全正确。顶级限定符在声明和函数类型中被忽略。然而,在定义中,它们在函数中仍然像往常一样表现。 (顶级限定符也被 typeid 和模板参数忽略,当匹配异常以捕获时,可能在其他一些情况下我已经忘记了。实际上,它们对非类类型返回值也没有影响。)
  • 关于const p 的最后一个示例:p=0; 是尝试更改p,但它没有未定义的行为,它只是格式错误。
【解决方案3】:

向我解释的方式,给定:

[const] TYPE * [const] VARIABLE

VARIABLE 用于通过*VARIABLE

指向TYPE 类型的data

通过*或多个*s画一条线

  1. 如果*左侧const,则它适用于 datadata 无法更改:*VARIABLE 无法分配,初始化时除外
  2. 如果*右侧const,则它适用于 VARIABLEVARIABLE 指向的内容不能更改:VARIABLE 不能赋值,除非在初始化时

所以:

          |              left  right
int       *       i1;
          |              no    no     can change *i1 and i1

int const *       i2;     
          |              yes   no     cannot change *i2 but can change i2

int       * const i3;
          |              no    yes    can change *i3 but i3 cannot be changed

int const * const i4;
          |              yes   yes    cannot change *i4 or i4

【讨论】:

  • const 绑定到左侧。除非左边没有任何东西,否则它绑定到右边
【解决方案4】:

int *const iconst 放在顶层,而 int const *i 没有。

第一个说指针i本身是不可变的,而第二个说指针指向的内存是不可变的。

只要const 紧接在标识符类型之前或之后出现,就被视为顶级限定符。

【讨论】:

  • 优秀而清晰的答案。附言int const *i 等于 const int *i(都是低级 const)。我使用const int *i(低级)更频繁地将其常量级别与int *const i(顶级)区分开来。
  • 我很难理解“只要 const 紧接在标识符类型之前或之后出现,就被认为是顶级限定符。”这是否不适用于int const *i,因为const 出现在标识符类型的中间,在这种情况下是int *
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-13
  • 1970-01-01
  • 2017-05-20
  • 2021-02-23
  • 2020-07-19
相关资源
最近更新 更多