在c ++中使用const ArrayType或ConstArrayType在一个数组中使用const元素

时间:2015-04-01 14:26:10

标签: c++ arrays const typedef

我将定义一些具有固定大小和const元素的数组 我尝试使用typedef,但似乎有些困惑:

typedef int A[4];
typedef const int CA[4];

const A a = { 1, 2, 3, 4 };
CA ca = { 1, 2, 3, 4 };

a[0] = 0;
ca[0] = 0;
a = ca;
ca = a;

所有分配都会导致上述代码中的语法错误,我认为a[0] = 0;在我的测试之前应该是合法的。

考虑指针,
结果更容易理解,p[0] = 0;cp = p;是正确的。

typedef int *P;
typedef const int *CP;

const P p = new int[4]{ 1, 2, 3, 4 };
CP cp = new int[4]{ 1, 2, 3, 4 };

p[0] = 0;
cp[0] = 0;
p = cp;
cp = p;

为什么cv-qualifier在指针和数组上表现不同?
是因为数组已经是一个const指针,那么编译器会进行一些隐式转换吗?

P.S。我在Visual Studio 2013上编译了代码。

4 个答案:

答案 0 :(得分:2)

这两个声明

const A a = { 1, 2, 3, 4 };
CA ca = { 1, 2, 3, 4 };

完全等效并声明常量数组。如果您将运行这个简单的程序(例如使用MS VC ++)

#include<iostream>

typedef const int CA[4];
typedef int A[4];

int main()
{
    std::cout << typeid( CA ).name() << std::endl;
    std::cout << typeid( const A ).name() << std::endl;

    return 0;
}

您将获得两个输出语句的相同结果

int const [4]
int const [4]

实际上你可以改写

#include<iostream>

typedef int A[4];
typedef const A CA;

int main()
{
    std::cout << typeid( CA ).name() << std::endl;
    std::cout << typeid( const A ).name() << std::endl;

    return 0;
}

具有相同的结果。

对于指针声明符,语义之间存在细微差别。您可以将cv-qualifiers与指针声明符一起使用

ptr-operator:
    * attribute-specifier-seqopt cv-qualifier-seqopt

那就是你可以写例如

typedef const int * const P;

(指向常量数据的常量指针)。

因此,如果你要写

typedef int *P;

然后写

typedef const P CP;

CP成为常量指针时。它指向的对象不是恒定的。只有指针本身是常量,可能不会更改。那是宣言

typedef const P CP;

相当于

typedef int * const CP;

不一样
typedef const int *CP;

在最后一个声明中,指针本身不是常量。它是指针指向的对象,此类型将是常量,并且不能使用此指针进行更改。

如果你有

,很快就会说
typedef int A[4];

然后

const A a = { 1, 2, 3, 4 };

相当于

const int a[4] = { 1, 2, 3, 4 };

如果你有

typedef int *P;

然后

const P p = new int[4]{ 1, 2, 3, 4 };

相当于

int * const p = new int[4]{ 1, 2, 3, 4 };

如果您有

之类的声明,请考虑到这一点
const int *p;

然后你不需要初始化指针,因为它不是常量。

当你有声明

int * const p = new int;

或喜欢

const int * const p = new int; 

你应该初始化指针,因为它是一个常量。否则编译器将发出错误。

答案 1 :(得分:2)

我一次又一次地搜索了cppreference并最终找到答案......

http://en.cppreference.com/w/cpp/language/array

据说

  

将cv-qualifiers应用于数组类型(通过typedef或template   类型操作)将限定符应用于元素类型,但任何   数组类型的元素是cv限定类型被认为是   拥有相同的cv资格。

// arr1 and arr2 have the same const-qualified type "array of 5 const char"
typedef const char CC;
CC arr1[5] = {}; 
typedef char CA[5];
const CA arr2 = {};

这正是我所要求的! 通常情况下,
typedef const PointerType p;表示无法修改p,但p指向的数据是可变的,typedef const Type *cp;表示cp是可变的,但cp指向的数据1}}是不变的。

但是对于一个数组,这两个样式是等价的!

答案 2 :(得分:0)

我并不是100%肯定你在问什么,但也许以下内容会有所帮助。

在第一种情况下,a[0]=0;失败,因为a的类型为const int[]。我喜欢从右到左阅读const。

typedef int IntegerArraySz4[4];
IntegerArraySz4 const a; // constant array, assignment not allowed

在第二种情况下,在指向常量整数数组的指针和指向整数数组的常量指针之间,typedef存在差异。再次,从右到左:

typedef int* IntPointer;
typedef int const* ConstantIntPointer;

// This is a constant pointer to some memory
IntPointer const p = new int[4] { 1, 2, 3, 4 };
p[2] = 1; // okay

// This is a pointer to some constant memory
ConstantIntPointer cp = new int [4] { 1, 3, 4, 5 };
cp[2] = 1; // error

答案 3 :(得分:0)

你需要一个C风格的数组,你需要使用一个宏:

#define A(x) int x[4]
#define CA(x) const int x[4]

将使用如下:

const A(a) = {1, 2, 3, 4};
CA(ca) = {1, 2, 3, 4};

但这看起来很令人困惑。似乎最好使用std::array<int, 4>。你可以用typedef

来做到这一点
typedef array<int, 4> A;
typedef const array<int, 4> CA;

将使用如下:

const A a = {1, 2, 3, 4};
CA ca = {1, 2, 3, 4};

请注意,您的其余代码是非法的,因为您无法分配到const arrayconst int[]