2016-09-27 14 views
13

Tại sao ủy ban C++ quyết định rằng tham chiếu const nên kéo dài tuổi thọ của thời gian?Tại sao tham chiếu const kéo dài tuổi thọ của các giá trị?

Thực tế này đã được thảo luận rộng rãi trực tuyến, kể cả ở đây trên stackoverflow. Tài nguyên được dứt khoát giải thích rằng đây là trường hợp có lẽ là GoTW này:

GotW #88: A Candidate For the “Most Important const”

lý do cho tính năng ngôn ngữ này là gì? Có biết không?

(Việc thay thế sẽ được rằng tuổi thọ của temporaries không được gia hạn bởi bất kỳ tài liệu tham khảo.)


My own lý thuyết vật nuôi cho các lý do là rằng hành vi này cho phép các đối tượng ẩn chi tiết thực hiện. Với quy tắc này, một hàm thành viên có thể chuyển đổi giữa trả về một giá trị hoặc một tham chiếu const tới một giá trị đã tồn tại bên trong mà không có bất kỳ thay đổi nào đối với mã máy khách. Ví dụ, một lớp ma trận có thể trả về các vectơ hàng và vectơ cột. Để giảm thiểu các bản sao, một hoặc cái khác có thể được trả lại dưới dạng tham chiếu tùy thuộc vào việc triển khai (hàng chính so với cột chính). Bất kỳ cái nào không thể được trả lại bằng cách tham chiếu phải được trả lại bằng cách tạo một bản sao và trả về giá trị đó (nếu các vectơ trả về là liền kề). Các nhà văn thư viện có thể muốn mất nhiều thời gian để thay đổi việc thực hiện trong tương lai (hàng chính vs cột chính) và ngăn chặn khách hàng viết mã mà phụ thuộc mạnh mẽ vào việc thực hiện là hàng chính hoặc cột lớn. Bằng cách yêu cầu khách hàng chấp nhận các giá trị trả về như const ref, lớp ma trận có thể trả về một trong hai tham số const hoặc các giá trị mà không có bất kỳ thay đổi nào đối với mã máy khách. Bất kể, nếu lý do ban đầu được biết, tôi muốn biết điều đó.

+0

Ví dụ về ma trận sẽ được giải quyết thanh lịch hơn bằng cách sử dụng đối tượng proxy. – 5gon12eder

+2

Bạn sẽ phải kiểm tra "Design & Evolution of C++" cho câu trả lời cuối cùng. Nhưng tôi mạnh mẽ nghi ngờ rằng câu hỏi này có một câu trả lời khách quan - lý thuyết vật nuôi cá nhân không quan trọng. – MSalters

+0

@ 5gon12eder Tôi nghĩ rằng những gì bạn đang đề xuất là giải pháp tôi đã cố gắng để empt trước bằng cách quy định rằng các vector trả về phải được tiếp giáp (vì lý do gì ...). – Praxeolitic

Trả lời

14

Nó đã được đề xuất vào năm 1993. Mục đích của nó là để loại bỏ việc xử lý không phù hợp của thời gian khi bị ràng buộc để tham khảo.

Quay lại sau đó, không có điều như RVO, vì vậy chỉ đơn giản là cấm việc ràng buộc của một tạm thời để tham khảo sẽ là một hit hiệu suất.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0345.pdf

+1

Wow, lúc đó tôi 10 tuổi. Thú vị để biết lý do thực sự. 1 cho liên kết đến bài báo. – skypjack

+2

@skypjack 1993 là năm tôi từ bỏ lập trình lần đầu tiên vì tôi muốn có một số cuộc phiêu lưu ... –

+0

Đoạn thứ hai của bạn không rõ ràng với tôi. Bạn có thể mô tả một trường hợp hình phạt hiệu suất của việc sao chép một tạm thời (có thể tránh được bởi RVO, nhưng được cho là không được thực hiện) có thể được phá vỡ bằng cách ràng buộc một tạm thời để tham khảo? Không có khóa học tạo ra một tham chiếu lơ lửng. –

2

Bạn không đặt câu hỏi tại sao tham chiếu const được phép liên kết với thời gian, nhưng chỉ đơn thuần là lý do tại sao chúng kéo dài tuổi thọ của những thời gian đó.

xem xét mã này:

struct A 
{ 
    void foo() const; 
}; 

A bar(); 

const A& a = bar(); 

a.foo();    // (1) 

Nếu tuổi thọ của tạm thời được trả về bởi bar() không được mở rộng, sau đó bất kỳ việc sử dụng của a (minh họa bởi các dòng (1)) sẽ dẫn đến hành vi không xác định. Điều này sẽ làm cho ràng buộc tham số không tham số const thành các thời gian hoàn toàn vô dụng.


EDIT (địa chỉ OP's comment):

Do đó, câu hỏi thực sự nên được tại sao một biến tham chiếu const (mà không phải là một tham số chức năng) được phép liên kết với một tạm thời. Tôi không biết lý do ban đầu cho nó (Richard Hodges' answer có thể là sự thật duy nhất), nhưng nó cung cấp cho chúng tôi một tính năng hữu ích. Xem xét ví dụ sau:

struct B 
{ 
    virtual void foo() const; 
}; 

B bar(); 

const B& b = bar(); 

b.foo();    // (1) 

Sự khác biệt duy nhất của ví dụ này từ ví dụ trước là B::foo() là ảo. Bây giờ, điều gì xảy ra nếu chúng tôi quyết định giới thiệu một lớp học mới D làm lớp con của B và thay đổi loại trả lại là bar() từ B thành D?

struct B 
{ 
    virtual void foo() const; 
}; 

struct D : B 
{ 
    virtual void foo() const; 
}; 

//B bar(); 
D bar(); 

const B& b = bar(); 

b.foo(); // This will call D::foo() 

// In the end the temporary bound by b will be correctly destroyed 
// using the destructor of D. 

Vì vậy, ràng buộc const tham chiếu đến thời gian đơn giản hóa việc tận dụng đa hình động cho các đối tượng được trả về theo giá trị.

+0

Câu trả lời đúng, bạn có thể thêm điều gì đó về các loại rvalue và lvalue của biểu thức tham chiếu không? – Trevir

+0

@Trevir Xin lỗi, nhưng tôi không thấy làm thế nào mà có thể cải thiện câu trả lời (liên quan đến câu hỏi của OP). – Leon

+1

Trừ khi tôi bối rối, câu trả lời này có vẻ hơi quá siêu. Tôi không biết liệu từ ngữ câu hỏi có gây hiểu nhầm hay không nhưng tôi không có ý nói rằng bằng cách nào đó nó có thể có ý nghĩa đối với các tham chiếu const liên kết thời gian nhưng không kéo dài thời gian sống của chúng. Câu hỏi được dự định là về lý do tại sao tham chiếu const có thể liên kết thời gian * và * kéo dài tuổi thọ của chúng. – Praxeolitic

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