2011-04-20 28 views
5

Làm thế nào để trình biên dịch C++ hoặc Java đảm bảo rằng không có trạng thái biến thành viên nào được thay đổi trong hàm thành viên const (có thể thay đổi được là ngoại lệ).Trình biên dịch đảm bảo rằng không có trạng thái thành viên dữ liệu nào được thay đổi trong hàm thành viên const? (hoặc trong C++ hoặc java)

Trình biên dịch có làm điều gì đó giống như đặt mã trong phân đoạn mã không thể ghi được hay gì đó tương tự không?

Trả lời

3

Trình biên dịch không đảm bảo. Không thể, vì không có quy tắc bằng ngôn ngữ cho biết rằng trạng thái biến thành viên không thể thay đổi trong chức năng thành viên const. Quy tắc duy nhất là bạn không thể thay đổi trạng thái thông qua con trỏ this (không cần bỏ đi const).

+0

Tham chiếu: 9.3.2/2 –

+1

OK. Tôi sẽ nâng DR, bởi vì đây không phải là cố ý (và bị mâu thuẫn ở nhiều nơi khác trong tiêu chuẩn). Bạn có thể sửa đổi 'mutable' (nếu không, điểm là gì), bạn có thể bỏ đi const, và bạn có thể sửa đổi rõ ràng đối tượng thông qua các con trỏ khác, không liên quan đến nó có thể tồn tại. –

+0

@James: Nhiều hoạt động trong số này dẫn đến hành vi không xác định. –

3

Để kiểm tra C++ const được thực hiện tại thời gian biên dịch thông qua logic của trình biên dịch. Nó sẽ đảm bảo rằng nếu một hàm được đánh dấu const thì sẽ không có thay đổi nào được thực hiện đối với các biến thành viên. Tôi không nghĩ rằng nó có liên quan đến việc lưu trữ mã thực thi.

Đối với Java, tôi không biết rằng có cùng một mô hình const.

1

Trình biên dịch C++ sẽ gắn cờ nếu bạn cố sửa đổi biến thành viên (trực tiếp hoặc gián tiếp bằng cách gọi hàm không const) trong hàm const (trừ khi biến đó được đánh dấu là có thể thay đổi). Bạn có thể làm việc này với dàn diễn viên. Trình biên dịch sẽ không (và không nên) làm bất cứ điều gì nhiều hơn để thực thi constness tại thời gian chạy.

Tôi không thể nói chuyện với Java.

0

Trong C++: const vòng loại của hàm chỉ làm cho mọi thành viên không thể thay đổi của lớp và this con trỏ const-đủ điều kiện trong phần thân hàm này. Đó là tất cả.

ADD:

Điều đó có nghĩa rằng nếu const chức năng rõ ràng hoặc ngầm truy cập this con trỏ như không const con trỏ nó sẽ tạo ra lỗi biên dịch.

0

Trong C++: Trình biên dịch phát hiện lỗi rõ ràng, đó là các hàm gọi của hàm không const trên biến thành viên (hoặc đối tượng này). Nó bao gồm nhà điều hành gọi =, vv Nó thường sẽ xuất ra "không thể chuyển đổi từ const ... T ... thành ... T ...".

Nếu bạn muốn bỏ qua điều đó, bạn có thể sử dụng const_cast.

Cần lưu ý rằng mặc dù độ chói của hàm không có nghĩa là trạng thái của đối tượng sẽ không thay đổi sau khi gọi. Ví dụ, với mã rằng:

class A 
{ 
public: 
    // stuff... 
    // 
    int* getPointer() const {return mpA;} 
private: 
    int* mpA; 
} 

bạn có thể có quyền truy cập vào các giá trị được trỏ đến bởi Mpa từ bên ngoài và sửa đổi nó ... Đối tượng Mpa tự nó sẽ không được sửa đổi (vì vậy constness của getPointer là được tôn trọng), nhưng độ chói của giá trị mà mpA trỏ tới không được đảm bảo. Nó thực sự sẽ là quá nhiều công việc để đảm bảo nó.

0

Trong C++, vòng loại const là bộ định tính loại. Trên thực tế, một tên đủ tiêu chuẩn được đặt tên là (sau tiêu chuẩn) là loại được xây dựng.

Khi thực hiện độ phân giải quá tải chức năng, trình biên dịch do đó sẽ áp dụng cơ chế thông thường ngăn bạn gọi số void foo(int) với tham số std::string làm đối số.

Họ có thể có, tuy nhiên, chẩn đoán tốt hơn cho lỗi cụ thể này, để giúp nhà phát triển.

Trong C++, điều này được minh họa đặc biệt bởi thực tế là const_cast có sẵn để loại bỏ các const-Ness của một đối tượng ... Chỉ có một tinh tế:

Đối tượng được khởi tạo tại tập tin phạm vi (globals, statics, ...) và tuyên bố const có thể được đặt trong bộ nhớ chỉ đọc theo quyết định của trình biên dịch, trong trường hợp này, hãy thử const_castHành vi không xác định.

0

Và một điểm khác để thêm các điểm nêu trên để làm cho nó đơn giản. Trong các hàm const, trình biên dịch biến nó thành con trỏ liên tục. vì vậy const int a = 10 ;, a = 20 rõ ràng là ném lỗi.

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