2011-10-27 32 views
38

const ở vòng loại "cấp cao nhất" có nghĩa là gì trong C++?Vòng loại const cấp cao nhất là gì?

Và các cấp khác là gì?

Ví dụ:

int const *i; 
int *const i; 
int const *const i; 
+3

Ví dụ, xin vui lòng? – bmargulies

+0

Tôi không biết ý bạn là gì bởi các ví dụ nhưng tôi đã thêm một số vòng loại const mà tôi quen thuộc. – user103214

+3

Đồng thời xem [Định nghĩa cv-qualifiers' ở cấp cao nhất trong tiêu chuẩn C++ 11 ở đâu?] (Http://stackoverflow.com/q/24676824/1708801) –

Trả lời

49

Một const vòng loại cấp cao nhất ảnh hưởng đến đối tượng riêng của mình. Những người khác chỉ có có liên quan với con trỏ và tham chiếu. Chúng không tạo đối tượng const và chỉ ngăn thay đổi thông qua đường dẫn bằng cách sử dụng con trỏ hoặc tham chiếu . Do đó:

char x; 
char const* p = &x; 

Đây không phải là một cấp cao nhất và không có đối tượng nào không thay đổi. Không thể sử dụng cụm từ *p để sửa đổi x, nhưng các biểu thức khác có thể là; x không phải là const. Đối với vấn đề đó

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

là hợp pháp và được xác định rõ ràng.

Nhưng

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

thời gian này, có một const cấp cao nhất trên x, vì vậy x là không thay đổi. Không biểu thức được phép thay đổi nó (ngay cả khi sử dụng const_cast). Trình biên dịch có thể đặt x trong bộ nhớ chỉ đọc và có thể giả định rằng giá trị của x không bao giờ thay đổi, bất kể mã nào khác có thể làm.

Để cung cấp cho con trỏ top-level const, bạn muốn viết:

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

Trong trường hợp này, p sẽ trỏ đến x mãi mãi; bất kỳ nỗ lực nào để thay đổi này là hành vi không xác định (và trình biên dịch có thể đặt p trong bộ nhớ chỉ đọc, hoặc giả định rằng *p đề cập đến x, bất kể mã nào khác).

+3

Rất rõ ràng, cảm ơn bạn :) – Seb

+6

Một điểm khác: khi viết các hàm, các vòng loại cấp cao nhất của các đối số sẽ bị loại bỏ. Điều này có nghĩa là 'void foo (char const)' và 'void foo (char)' là cùng một hàm (và trên thực tế chúng có thể được hoán đổi). Lý do là kể từ khi đối số được thực hiện bởi bản sao, người gọi không quan tâm liệu bản sao có thể được sửa đổi hay không, vì vậy nó minh bạch cho cô ấy. –

+7

@MatthieuM. Điểm tốt, mặc dù không chính xác đúng như đã nêu. Các vòng loại cấp cao nhất được bỏ qua trong khai báo và trong loại hàm. Tuy nhiên, trong định nghĩa, chúng vẫn hoạt động bình thường trong hàm. (Các vòng loại cấp cao nhất cũng bị bỏ qua bởi các tham số 'typeid' và mẫu, khi kết hợp các ngoại lệ để bắt và có thể trong một số trường hợp khác tôi đã quên. Trong thực tế, chúng cũng không ảnh hưởng đến các giá trị trả về kiểu không phải lớp.) –

10

int *const i đặt const ở cấp cao nhất, trong khi int const *i thì không.

Đầu tiên nói rằng con trỏ i chính nó là không thay đổi, trong khi thứ hai nói rằng bộ nhớ con trỏ trỏ đến là không thay đổi.

Bất cứ khi nào const xuất hiện ngay trước hoặc sau loại định danh, được coi là vòng loại cấp cao nhất.

+0

Câu trả lời tuyệt vời và rõ ràng. P.S. 'int const * i' bằng' const int * i' (tất cả đều là const cấp thấp). Tôi sử dụng 'const int * i' (mức thấp) để phân biệt mức const của nó thường xuyên hơn từ' int * const i' (cấp cao nhất). – dotslash

5

Cách nó đã giải thích cho tôi, đưa ra:

[const] TYPE * [const] VARIABLE 

BIẾN được sử dụng để trỏ đến dữ liệu loại LOẠI qua *VARIABLE

Vẽ một đường qua * hoặc nhiều * s

  1. Nếu có một const đến trái của * nó áp dụng cho các dữ liệudữ liệu không thể thay đổi: *VARIABLE không thể được chỉ định, trừ lúc khởi tạo
  2. Nếu có một const đến đúng của * nó áp dụng cho các BIẾN và những gì BIẾN điểm đến không thể thay đổi: VARIABLE không thể được chỉ định, ngoại trừ tại initiali zation

Vì vậy:

  |    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 
+0

'const' liên kết với bên trái. trừ khi không có gì ở bên trái, sau đó nó liên kết với bên phải – sp2danny

Các vấn đề liên quan