"Được phép" là trái ngược với "bị chặn", nhưng nó cũng ngược lại với "bị cấm". Bạn đã thấy rằng việc sửa đổi đối tượng const của bạn không bị ngăn chặn, nhưng điều đó không chính xác có nghĩa là nó được cho phép.
Sửa đổi đối tượng const không được "cho phép" theo nghĩa là "được phép". Hành vi của chương trình của bạn không được xác định theo tiêu chuẩn (xem 6.7.3/5). Nó chỉ như vậy sẽ xảy ra rằng trên thực hiện của bạn, trên chạy, bạn thấy giá trị 3. Trên thực hiện khác hoặc vào một ngày khác, bạn có thể thấy một kết quả khác nhau.
Tuy nhiên, nó không bị "ngăn chặn", vì với cách thức hoạt động của C, việc phát hiện nó ở thời gian biên dịch là một vấn đề dừng. Phát hiện nó trong thời gian chạy yêu cầu kiểm tra thêm ở tất cả các truy cập bộ nhớ. Tiêu chuẩn được thiết kế không áp đặt nhiều chi phí cho việc triển khai.
Lý do đúc đi const được hỗ trợ ở tất cả, là bởi vì nếu bạn có một con trỏ const đến một đối tượng không const, ngôn ngữ cho phép bạn (trong cả hai giác quan) để sửa đổi đối tượng đó. Để làm như vậy bạn cần phải loại bỏ vòng loại const. Hậu quả của việc này là các lập trình viên cũng có thể loại bỏ các vòng loại const từ các con trỏ tới các đối tượng thực sự là const.
Dưới đây là một (hơi ngớ ngẩn) ví dụ về mã mà loại bỏ khuôn khổ vòng loại const vì lý do đó:
typedef struct {
const char *stringdata;
int refcount;
} atom;
// returns const, because clients aren't allowed to directly modify atoms,
// just read them
const atom *getAtom(const char *s) {
atom *a = lookup_in_global_collection_of_atoms(s);
if (a == 0) {
// error-handling omitted
atom *a = malloc(sizeof(atom));
a->stringdata = strdup(s);
a->refcount = 1;
insert_in_global_collection_of_atoms(a);
} else {
a->refcount++;
}
return a;
}
// takes const, because that's what the client has
void derefAtom(const atom *a) {
atom *tmp = (atom*)a;
--(tmp->refcount);
if (tmp->refcount == 0) {
remove_from_global_collection_of_atoms(a);
free(atom->stringdata);
free(atom);
}
}
void refAtom(const atom *a) {
++(((atom*) a)->refcount);
}
Đó là ngớ ngẩn vì một thiết kế tốt hơn sẽ được chuyển tiếp-tuyên bố atom
, để làm cho con trỏ tới hoàn toàn mờ đục và cung cấp chức năng truy cập chuỗi dữ liệu. Nhưng C không yêu cầu bạn đóng gói mọi thứ, nó cho phép bạn trả về con trỏ tới các kiểu được xác định đầy đủ và nó muốn hỗ trợ kiểu sử dụng const này để trình bày một khung nhìn chỉ đọc của một đối tượng "có thể thay đổi" được.
Nguồn
2010-09-14 14:33:13
Vì C là hiện thân hoàn hảo của việc gõ yếu. "Các loại chỉ dành cho vui, nếu bạn không thích kiểu nào đó, chỉ cần bỏ nó";) – delnan
Luật Osborn http://www.anvari.org/fortune/Fortune_Cookies/95_osborn-s-law-variables-won- t.html – Jaydee
Bởi vì C & C++ sẽ cho phép bạn làm bất cứ điều gì bạn muốn, ngay cả khi bạn muốn làm điều gì đó thực sự, thực sự ngu ngốc. –