2010-01-18 44 views
10

Mã sau hoạt động như thế nào trong C++? Nó có hợp lý không?Khởi tạo chữ cho tham chiếu const

const int &ref = 9; 
const int &another_ref = ref + 6; 

Tại sao C++ cho phép khởi tạo theo nghĩa đen cho tham chiếu const khi cùng không được phép tham chiếu không phải const? Ví dụ:

const int days_of_week = 7; 
int &dof = days_of_week; //error: non const reference to a const object 

Điều này có thể được giải thích bằng cách sử dụng tham chiếu không tham chiếu để thay đổi giá trị của biến mà nó đang đề cập đến. Do đó, C++ không cho phép tham chiếu không const đến một biến const.

Đây có phải là giải thích có thể không? C++ không cho phép:

int &ref = 7; 

Bởi vì đó không phải là hợp lý, nhưng:

const int &ref = 7; 

là gần như tương đương với:

const int val = 7; 

khởi Vì vậy, theo nghĩa đen được phép cho các biến const.

P .: Tôi hiện đang học LDPman's C++ Primer.

Trả lời

7

Vì vậy, bạn có thể viết mã như thế này:

void f(const string & s) { 
} 

f("foobar"); 

Mặc dù nói đúng những gì đang thực sự xảy ra ở đây là không phải là chữ được ràng buộc với một tham chiếu const - thay vì một đối tượng chuỗi temprary được tạo ra:

string("foobar"); 

và chuỗi không tên này bị ràng buộc với tham chiếu. Lưu ý rằng nó thực sự là khá bất thường để tạo các biến tham chiếu không tham số như bạn đang làm - mục đích chính của tài liệu tham khảo là phục vụ như các tham số hàm và giá trị trả về.

6

tài liệu tham khảo liên tục có thể được khởi tạo với literals và temporaries vì ​​bạn trivially có thể chuyển đổi chúng để biến rõ ràng:

int const& ans = 42; 
// tranformed: 
int __internal_unique_name = 42; 
int const& ans = __internal_unique_name; 

Hoặc khi thời gian tồn tại không được gia hạn, chẳng hạn như một tham số chức năng:

f("foobar"); 
// transformed: 
{ 
    string __internal_unique_name = "foobar"; 
    f(__internal_unique_name); 
} 

(Lưu ý khối rõ ràng trong trường hợp này.)

Mặc dù có thể làm điều gì đó tương tự trong trường hợp không liên tục, điều đó không cho phép trong currenct C++. Tuy nhiên, C++ 0x (tiêu chuẩn tiếp theo) sẽ có tham chiếu giá trị r.


Nếu nó không được rõ ràng, ref + 6 từ mã của bạn tạo ra một đối tượng tạm thời, mà bạn có thể hình dung như sau:

int const& ref = int(9); 
int const& another_ref = int(ref + 6); 

// transformed: 
int __A = 9; 
int const& ref = __A; 
int __B = ref + 6; 
int const& another_ref = __B; 

Điều này có thể giúp bạn hiểu/hình dung những gì đang xảy ra, nhưng bạn nên không viết mã thực như thế này.Ngoài ra tôi đã sử dụng tên gạch dưới kép để minh họa cho những tên đó là các chi tiết thực hiện (được sử dụng bởi trình biên dịch) và không nên được bạn sử dụng. Bất kỳ tên nào có chứa dấu gạch dưới liền kề được dành riêng cho việc thực hiện C++.

+0

+1. Nhưng tôi nghĩ ví dụ thứ hai của bạn sẽ được chuyển thành { chuỗi __internal_unique_name ("foobar"); f (__ internal_unique_name); } – mmmmmmmm

+0

@rstevens: không quan trọng: chuyển đổi không được rõ ràng, trong trường hợp này chúng giống nhau. –

2

Quy tắc chuẩn của bạn sẽ tuân thủ quy tắc chuẩn C++ trong đó thời gian tồn tại của giá trị tạm thời được gắn với thời lượng của tham chiếu const được gán. Xem bài viết GoTWGotW #88: A Candidate For the “Most Important const” để biết thêm chi tiết.

Ví dụ: triển khai ScopeGuard, được mô tả bởi Alexandrescu và Marginean trong bài viết của Dr. Dobbs "Generic: Change the Way You Write Exception-Safe Code — Forever" tùy thuộc vào hành vi này.

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