Tại sao const lại ngụ ý liên kết nội bộ trong C ++, trong khi nó không có trong C?


82

Xem chủ đề. Họ đang nghĩ gì?

CẬP NHẬT: Đã thay đổi từ "tĩnh" thành "liên kết nội bộ" để đỡ nhầm lẫn.

Để đưa ra một ví dụ ... Đưa nội dung sau vào một tệp:

const int var_a = 1;
int var_b = 1;

... và biên dịch g++ -c test.cppchỉ với bản xuất var_b.

Câu trả lời:


112

Tôi tin ý bạn là

Tại sao const ngụ ý liên kết nội bộ trong C ++

Đúng là nếu bạn khai báo một đối tượng const ở phạm vi không gian tên, thì nó có liên kết nội bộ.

Phụ lục C ( C ++ 11, C.1.2 ) đưa ra cơ sở lý luận

Thay đổi: Tên của phạm vi tệp được khai báo rõ ràng const, và không được khai báo rõ ràng extern, có liên kết nội bộ, trong khi trong C nó sẽ có liên kết bên ngoài

Lý do: Bởi vì các đối tượng const có thể được sử dụng làm giá trị thời gian biên dịch trong C ++, tính năng này thúc giục các lập trình viên cung cấp các giá trị khởi tạo rõ ràng cho mỗi const. Tính năng này cho phép người dùng đặt các đối tượng const trong các tệp tiêu đề được bao gồm trong nhiều đơn vị biên dịch.


Có vẻ như các đối tượng toàn cục không phải const cũng có thể được khởi tạo, nhưng tại sao tiêu chuẩn không cung cấp cho nó liên kết nội bộ?
Yong Li

13

Như litb đã nói, constcác đối tượng có liên kết nội bộ trong C ++. Đó là vì chúng được sử dụng như thế này:

// a.cpp
const int BUFSIZE = 100;
char abuf[BUFSIZE];

// b.cpp
const int BUFSIZE = 256
int bbuf[BUFSIZE];

6

Const và static là những khái niệm trực giao trong cả C và C ++.

Các consttừ khóa cho trình biên dịch để không cho phép biến xuất hiện như vế trái của bất kỳ biểu hiện - về cơ bản làm cho nó read-only.

Trong C, statictừ khóa có một số cách sử dụng tùy thuộc vào những gì nó được áp dụng. Khi được áp dụng cho một biến của một hàm, nó chỉ ra rằng biến đó không được lưu trữ trong phạm vi cục bộ của một hàm, nhưng có thể truy cập được qua các lệnh gọi của nó. Khi được áp dụng cho một biến hoặc hàm toàn cục, nó chỉ có thể truy cập được đối với một tệp cụ thể - nói cách khác, nó chỉ có thể truy cập được trong đơn vị biên dịch (trừ khi được khai báo extern).

Trong C ++, statictừ khóa có thể được sử dụng trong định nghĩa lớp, để tạo một biến hoặc các hàm được chia sẻ trên tất cả các trường hợp của lớp, thay vì cục bộ cho mỗi trường hợp. Hơn nữa, một hàm lớp tĩnh trong C ++ chỉ có thể truy cập các biến tĩnh của lớp đó (hoặc các lớp mà nó có quyền truy cập). Bây giờ, trong C ++ constcung cấp cho các thành viên liên kết nội bộ với đơn vị biên dịch trừ khi chúng được khai báo rõ ràng extern- đây có thể là những gì bạn đang đề cập đến nó. Điều này cho phép các hằng số thời gian biên dịch được chia sẻ giữa các đơn vị thông qua việc sử dụng các tệp tiêu đề. Tuy nhiên, hãy nhớ rằng các thành viên không thực sự tĩnh - đúng hơn là hằng số được biên dịch vào từng vị trí nơi nó được tham chiếu.


6

Trong C & C ++, thuật ngữ static có nhiều nghĩa (nó có thể chi phối liên kết và lưu trữ) Bạn sẽ phải đọc D&E của Stroustrup để đánh giá cơ sở lý luận của anh ta - nhưng khi bạn khai báo một biến là const ở phạm vi không gian tên, nó sẽ tự động có liên kết nội bộ - ngược lại trong C bạn phải khai báo nó static để buộc nó có liên kết nội bộ.

Tất nhiên trong C ++, việc sử dụng tĩnh để kiểm soát liên kết đã không còn được dùng nữa, không gian tên ẩn danh có thể được sử dụng để mô phỏng liên kết nội bộ trong C ++.

Các biến const trong C ++ được cho là thay thế hằng số tiền xử lý - và vì hằng số tiền xử lý chỉ hiển thị trong các tệp xác định chúng, tương tự, const tự động làm cho biến chỉ hiển thị trong tệp định nghĩa nó.


4

Những khái niệm đó là trực giao và không nên được coi là cùng một thứ.

Constness là một quyền truy cập: nó chỉ cho biết biến của bạn nên chỉ đọc (const) hay ghi-đọc (không phải const).

Tính tĩnh là một thuộc tính thời gian tồn tại (và bản địa hóa bộ nhớ về mặt kỹ thuật): nó cho biết liệu biến sẽ là toàn cục trong phạm vi của một lớp (khi ở trong một lớp) hay một đơn vị dịch (khi được sử dụng với một biến toàn cục được xác định trong cpp) .


-2

Nó không, và ví dụ rõ ràng nhất là nếu bạn có một biến thành viên const (tất nhiên là được khởi tạo bởi phương thức khởi tạo), nó sẽ không được chia sẻ bởi tất cả các đối tượng của lớp đó, mà là riêng lẻ cho từng đối tượng.

class A {
public:
  A(int newx) : x(newx);
private
  int x;
}

litb đưa ra câu trả lời tốt nhất, ở trên.


Không phải luôn luôn sao? (litb)
RastaJedi

-5

Nó không. Viết như sau:

const int i = 0;

không tạo itĩnh (trong C hoặc C ++).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.