2010-02-23 42 views
9

Ai có thể giải thích cho tôi tại sao có sự khác biệt giữa hai câu lệnh này?Khởi tạo tham chiếu trong C++

class A{}; 

const A& a = A();   // correct 

A& b = A();    // wrong 

Nó nói khởi không hợp lệ tham chiếu không const loại A& từ một tạm thời loại A

Tại sao const vấn đề ở đây?

Trả lời

14

Tham chiếu không phải const phải được khởi tạo bằng giá trị l. Nếu bạn có thể khởi tạo chúng với thời gian, sau đó những gì sau đây sẽ làm gì? tài liệu tham khảo

int& foo = 5; 
foo = 6; // ?! 

const có thuộc tính đặc biệt mà họ kéo dài tuổi thọ của trọng tài, và vì chúng là const, không có khả năng rằng bạn sẽ cố gắng sửa đổi một cái gì đó mà không ngồi trong bộ nhớ. Ví dụ:

const int& foo = 5; 
foo = 6; // not allowed, because foo is const. 

Hãy nhớ rằng tham chiếu thực sự phải đề cập đến điều gì đó, không chỉ là các biến tạm thời. Ví dụ: nội dung sau hợp lệ:

int foo = 5; 
int& bar = foo; 
bar = 6; 
assert(foo == 6); 
+1

Chờ đợi, điều đó có nghĩa là tôi có thể sử dụng 'const classA & ref = ReturnsClassAByValue();'? Tôi nghĩ nhiệt độ sẽ chết trên hàng kế tiếp. – Lucas

+2

Có, bạn có thể sử dụng nó. Tạm thời sẽ kéo dài miễn là biến tham chiếu thực hiện: http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!378.entry –

+1

Tuyệt vời, cảm ơn. Trên SO, bạn học một cái gì đó mới mỗi ngày ... – Lucas

1

Đối với giá trị tạm thời/rvalue, bạn chỉ có thể có tham chiếu const.

Bạn có thể có tham chiếu không tham chiếu đến giá trị không tạm thời/lvalue.

A a; 
A& b = a; 

Tôi tin rằng lý do tại sao để củng cố thực tế là một rvalue tạm thời vì có ít giá trị trong việc có thể sửa đổi cái gì đó sẽ biến mất trong giây lát.

+1

Đã cấp; Tôi nghĩ rằng OP đang tìm kiếm lý do tại sao. – fbrereto

1

Trong ngôn ngữ C++, việc gắn một tham chiếu không const vào một giá trị không hợp lệ, trong khi đó là hoàn toàn OK để đính kèm tham chiếu const vào một giá trị. Ví dụ, đây là hợp pháp

const int& r = 5; 

trong khi đây không phải là

int &r = 5; // ERROR 

Một đối tượng tạm thời loại A trả về bởi sự biểu hiện A() là một rvalue, vì vậy các quy tắc trên được áp dụng trong trường hợp của bạn là tốt.

+0

Giá trị rvalue là giá trị tạm thời chưa được đặt tên, như giá trị trả về của hàm. – thebretness

+0

@thebretness: Không nhất thiết. Ví dụ, một hằng số enum là một rvalue, nhưng nó là * có tên *. – AnT

3

Thuật ngữ này hơi khó hiểu; bạn có thể muốn nghiên cứu thêm một chút. Đây là câu trả lời ngắn gọn mặc dù:

Bạn đang gán một đối tượng tạm thời (kết quả của việc gọi hàm tạo của lớp) vào một biến. Một đối tượng tạm thời là một giá trị R. Bạn không thể gán giá trị R cho tham chiếu không phải const.

Bạn được phép chỉ định giá trị R cho tham chiếu const, mặc dù lý do cho phép nó khá mơ hồ.

0

Bởi vì tiêu chuẩn nói vậy:

§8.5.3.5 ... Nếu không, các tài liệu tham khảo sẽ là một tài liệu tham khảo giá trị trái để một kiểu const non-volatile ...

Tuy nhiên, nếu bạn muốn nó rất nhiều, bạn có thể lấy nó:

#include <iostream> 
int main() 
{ 
    const int & cr=5; 
    int & r=const_cast<int &>(cr); 
    r=6; 
    std::cout<<r; 
} 
// outputs 6 with c++/clang++, Debian 8, amd64 

Nhưng lưu ý rằng cr liên tục phải không const nữa cũng vậy, và bạn phải chịu hành vi không xác định. (§1.9 (4))

Theo đề xuất của mã trên, không có lý do kỹ thuật nào cho sự khác biệt. Thay vào đó, các nhà thiết kế đã có những cơn ác mộng về những gì người dùng sẽ làm với tham chiếu không const để tạm thời.

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