2012-08-23 7 views
5

Tôi đã thấy một lần trong một số trường hợp.C++ const được sử dụng hai lần trong khai báo mảng tĩnh

Có một chuỗi con trỏ tạo sự khác biệt không?

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]; 

Hiểu biết của tôi là b. không hợp lệ, nhưng nếu sử dụng const hai lần hợp lệ, mục đích của nó là gì?

Trả lời

12

const TYPE * x;

Có nghĩa là điểm x trỏ đến là const.

TYPE * const x;

Có nghĩa là con trỏ x là const.

Kết hợp 2 bạn nhận được:

const TYPE * const x;

Có nghĩa là con trỏ và điều được trỏ đến đều là const.

+0

Cảm ơn bạn đã trả lời nhanh chóng. Tôi sẽ đánh dấu chính xác vào ngày mai. – Jim

0

Trong khối mã đầu tiên bạn có bản sao dự phòng const trong dòng thứ hai, không có hiệu lực. (Trong thực tế, trình biên dịch tốt sẽ cảnh báo bạn về điều này.) Bạn đang khai báo một mảng 5 const TYPE s, đúng vậy.

Khối mã thứ hai có hai kịch bản khác nhau: Dòng đầu tiên làm cho một mảng trong số năm mutable con trỏ để const TYPE s, trong khi sau này làm cho một mảng trong số năm liên tục con trỏ để const TYPE s.

Lưu ý rằng bạn phải khởi tạo một mảng các hằng số: Vì bạn không thể thay đổi các giá trị sau này, nên việc xác định chúng không được khởi tạo là vô nghĩa.

+0

Thực ra, bạn có thể ném bao nhiêu 'const' vào một kiểu tùy thích. Chúng là không đáng kể. – bitmask

+0

@bitmask: Oh OK, đã sửa. Bạn sẽ nhận được một trình biên dịch cảnh báo từ trình biên dịch hợp lý, mặc dù :-) Cảm ơn! –

+0

Rất tiếc, tôi có thể đã trộn lẫn C và C++ tại đây. Lỗi của tôi. – bitmask

1

Bạn có thể áp dụng bất kỳ loại vòng loại cv nào (const hoặc volatile) cho bất kỳ loại nào, bao gồm các loại đủ điều kiện cv - chưa có trong tuyên bố giống nhau. Tuy nhiên, họ ràng buộc mạnh mẽ hơn bất kỳ nhà điều hành, về ưu tiên và có thể được áp dụng trên cả hai mặt của các loại trình độ:

// 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 

khai báo giống hệt nhau, một hằng số T. Nếu T đã có vòng loại cv, điều này sẽ không thay đổi ý nghĩa của chứng chỉ bổ sung.

Bây giờ, để được ưu tiên; Bạn có thể nói: "Tôi muốn có một con trỏ đến một hằng số T":

const T (* tp); 

mà thường được viết dưới dạng

const T* tp; 

const liên kết mạnh hơn * anyway.Trong cùng một khuôn mẫu, bạn có thể định nghĩa một biến đó là "liên tục nhưng chỉ ở một mutable T":

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

mà thường được viết như

T* const tp = 0; 

Trong bối cảnh đó các nhà điều hành subscript [] là được áp dụng - với cùng mức độ ưu tiên như trong các biểu thức.

0

Sử dụng const hai lần trên một loại là bất hợp pháp trong C++ 2003 nhưng hợp pháp trong C++ 2011 (xem 7.1.6.1 [decl.type.cv] đoạn 1: "Dự phòng cv thừa sẽ bị bỏ qua"). Khi bạn sử dụng

static const TYPE const name[5]; 

bạn đã thực hiện TYPE không đổi hai lần. Tuy nhiên, lưu ý rằng tuyên bố này là bất hợp pháp trong C++ 2011, bởi vì bạn cần khởi tạo một đối tượng const khi khai báo nó. Ý nghĩa của

const TYPE 

TYPE const 

là hoàn toàn tương đương: Trong cả hai trường hợp, bạn làm hằng TYPE đối tượng. Để nhất quán, tôi luôn đặt const ở bên phải vì mọi loại trừ loại cấp cao nhất const phải được đặt ở bên phải (tốt, trừ khi một số hướng dẫn mã hóa ủy thác khác nhau nhưng tôi đang chiến đấu với hướng dẫn mã hóa ngớ ngẩn).

Khi sử dụng con trỏ, suy nghĩ trở nên khác biệt. Có hai loại liên quan: loại chỉ vào loại và con trỏ. Mỗi người trong chúng có thể được thực hiện const riêng:

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 

Cách tốt nhất để tìm ra những gì được làm const là để đọc các khai báo kiểu từ phải sang trái. Tất nhiên, điều này giả định rằng vòng loại const được đưa vào đúng vị trí. Bạn có thể thay thế const theo volatile hoặc const volatile trong cuộc thảo luận ở trên và áp dụng cùng một lý do.