7

const我之前在数组的声明中见过两次static,现在我正在创建自己的静态数组,我想知道为什么在某些情况下需要两次 const。

有一个指针数组会有所不同吗?

a. static const TYPE name[5];
b. static const TYPE const name[5];

c. static const TYPE* name[5];
d. static const TYPE* const name[5];

我的理解是b.无效的,但是如果两次使用 const 是有效的,它的目的是什么?

4

4 回答 4

16
const TYPE* x;

表示 x 指向的东西是 const。

TYPE* const x;

表示指针 x 是 const。

结合你得到的2:

const TYPE* const x;

这意味着指针和指向的东西都是常量。

于 2012-08-23T22:07:17.450 回答
1

您可以将任何 cv 限定符(constvolatile)应用于任何类型,包括 cv 限定类型——但不能在同一个声明中。但是,就优先级而言,它们比任何运算符绑定得更牢固,并且可以应用于限定类型的两侧:

// Let T by any type:
T const tr;
const T tl;
const T const tlr; // only in C
const const const const const T t5; // only in C
typedef const T CT;
CT const tcc; // fine, although CT was already const

声明完全相同,一个常量T。如果T已经有 cv 限定符,这不会改变附加限定的含义。

现在,优先;你可以说“我想要一个指向常量的指针T”:

const T (* tp);

通常写成

const T* tp;

因为const绑定比*无论如何都要强。在相同的模式中,您可以定义一个“恒定但指向可变T”的变量:

T (* const tp) = 0; // must be initialised, because tp is immutable

通常写为

T* const tp = 0;

以同样的[]方式应用下标运算符——与表达式中的优先级相同。

于 2012-08-23T22:25:05.180 回答
0

在第一个代码块中,您const在第二行中有一个冗余副本,这没有任何影响。(事实上​​,好的编译器会警告你。)你声明了一个 5const TYPE的数组,就是这样。

第二个代码块有两种不同的场景:第一行创建了一个包含五个指向 s 的可变指针const TYPE的数组,而后一行创建了一个包含五个指向 s 的常量指针的数组const TYPE

请注意,您必须初始化一个常量数组:由于您以后无法更改这些值,因此将它们定义为未初始化是没有意义的。

于 2012-08-23T22:10:22.373 回答
0

在 C++ 2003 中对一个类型使用const两次是非法的,但在 C++ 2011 中是合法的(参见 7.1.6.1 [decl.type.cv] 第 1 段:“冗余 cv 限定被忽略。”)。当你使用

static const TYPE const name[5];

你做了TYPE两次常数。但是请注意,此声明在 C++ 2011 中也是非法的,因为您需要const在声明对象时对其进行初始化。的意思

const TYPE

TYPE const

是绝对等价的:在这两种情况下,您都使TYPE对象保持不变。为了保持一致性,我总是把const右边放在右边,因为除了顶级类型之外的每一个都const必须放在右边(好吧,除非某些编码指南要求不同,但我正在与愚蠢的编码指南作斗争)。

使用指针时,想法变得不同。涉及到两种类型:类型指向类型和指针。每一个都可以单独制作const

TYPE const*       ptr1(0);  // non-const pointer to const TYPE
TYPE* const       ptr2(0);  // const pointer to non-const TYPE
TYPE const* const ptr3(0);  // const pointer to const TYPE

弄清楚是什么的最好方法是const从右到左阅读类型声明。当然,这假设const限定符被放置在正确的位置。您可以替换constvolatileconst volatile在上面的讨论中,并且同样的推理适用。

于 2012-08-23T22:25:07.530 回答