2011-11-15 38 views
7

này kết quả đầu ra F~ nhưng tôi đã mong ~FKHÔNG phải là const quan trọng nhất .. nhưng đây là gì?

#include <iostream> 

struct Foo { 
    int _x; 
    operator const int &() const {return _x;} 
    ~ Foo() {std :: cout << "~";} 
}; 

void foo (const int &) 
{ 
    std :: cout << "F"; 
} 

int main() 
{ 
    foo (Foo()); 
} 

tôi xây dựng này như một phản ví dụ để chứng minh rằng hầu hết quan trọng const là một ngoại lệ chứ không phải là một quy tắc. Nó thường được viết dưới dạng

khi một tham chiếu const liên kết với một tạm thời, sau đó cuộc đời của đó tạm thời được mở rộng đến tuổi thọ của các tài liệu tham khảo

Tôi đã cố gắng để minh họa rằng, mặc dù Foo() là tạm thời, tham chiếu đến _x được toán tử chuyển đổi trả về và mã ở trên không an toàn.

Nhưng đầu ra dường như chứng minh rằng ví dụ an toàn, tuổi thọ của tạm thời Foo() được mở rộng bởi sự tồn tại của tham chiếu const cho một trong các thành viên của nó.

Điều này có đúng không? Tiêu chuẩn này được chỉ định ở đâu?

+0

Trở tài liệu tham khảo là thường xuyên hơn một ý tưởng tồi hơn một tốt nhất. Đây là một ví dụ điển hình về điều này. –

+0

@ R.MartinhoFernandes Vì vậy, bạn khai báo 'toán tử []' là ...? – curiousguy

Trả lời

6

Quy tắc chung, liên quan đến thời gian, là cuộc sống của họ kết thúc khi biểu thức đầy đủ là một phần của kết thúc (không chính thức khi đạt đến số ;).

12,2 đối tượng tạm thời

3/ [...] đối tượng tạm thời bị phá hủy như là bước cuối cùng trong việc đánh giá đầy đủ biểu thức (1.9) mà (giải nghĩa từ vựng) chứa các điểm mà họ đã được tạo. Điều này đúng ngay cả khi đánh giá đó kết thúc bằng việc ném một ngoại lệ. Các tính toán giá trị và tác dụng phụ của việc phá hủy một đối tượng tạm thời chỉ được liên kết với biểu thức đầy đủ, không phải với bất kỳ biểu thức con cụ thể nào.

1

Đó là vì tạm thời tồn tại trong suốt thời gian gọi hàm. Khi bạn làm foo (Foo()); đây là những gì sẽ xảy ra:

  1. tạm Foo được contructed, sau đó
  2. operator const int& được kêu gọi tạm thời
  3. foo() được gọi và điều này kết quả đầu ra F
  4. lần foo() lợi nhuận tạm thời Foo bị phá hủy và kết quả đầu ra này ~
+0

Để xây dựng: mã an toàn miễn là 'foo' không lưu trữ tham chiếu. –

1

Không có phép thuật ở đây. Tất cả các đối số hàm đều nằm trong phạm vi của người gọi, bao gồm cả thời gian chờ. Tạm thời Foo() được xây dựng trong phạm vi của người gọi và bị phá hủy ở cuối dòng.

Vì vậy, bất kể chức năng foo() nào xảy ra trước khi đối số của nó trong main() bị hủy.

0

Nhưng cá thể Foo của bạn ở đây sẽ luôn hoạt động cho đến khi dấu chấm phẩy kết thúc câu lệnh được tạo. Việc chuyển một tham chiếu đến một thành viên vào một cuộc gọi hàm đã không thay đổi điều đó.

Hãy thử:

int const &ref = Foo(); 
foo(ref); 

so

Foo const &ref = Foo(); // or function returning temp 
foo(ref); 
Các vấn đề liên quan