2009-03-23 19 views
15

Trong một dự án tôi duy trì, tôi thấy rất nhiều mã như thế này cho đơn giản get/set phương phápViệc sử dụng tham chiếu const đi tới các kiểu nguyên thủy là gì?

const int & MyClass::getFoo() { return m_foo; } 

void MyClass::setFoo(const int & foo) { m_foo = foo; } 

điểm trong việc đó thay vì những điều sau đây là gì?

int MyClass::getFoo() { return m_foo; } // Removed 'const' and '&' 

void MyClass::setFoo(const int foo) { m_foo = foo; } // Removed '&' 

Chuyển tham chiếu đến kiểu nguyên thủy sẽ yêu cầu cùng một nỗ lực (hoặc nhiều hơn) khi chuyển giá trị của loại, phải không?
Nó chỉ là một số sau khi tất cả ...
Đây có phải là một số cố gắng tối ưu hóa vi mô hoặc có một lợi ích thực sự?

Trả lời

20

Sự khác biệt là nếu bạn nhận được kết quả đó vào tham chiếu, bạn có thể theo dõi các thay đổi của biến thành viên nguyên trong tên biến của riêng bạn mà không cần nhớ lại hàm.

const &int x = myObject.getFoo(); 
cout<<x<<endl; 
//... 
cout<<x<<endl;//x might have changed 

Đây có thể không phải là lựa chọn thiết kế tốt nhất và rất nguy hiểm khi trả về tham chiếu (const hoặc không), trong trường hợp biến được giải phóng khỏi phạm vi được trả về. Vì vậy, nếu bạn trả về một tham chiếu, hãy cẩn thận để chắc chắn rằng nó không phải là một biến nằm ngoài phạm vi.

Có một sự khác biệt nhỏ đối với công cụ sửa đổi, nhưng một lần nữa có thể không phải là thứ đáng làm hoặc dự định.

void test1(int x) 
{ 
    cout<<x<<endl;//prints 1 
} 

void test2(const int &x) 
{ 
    cout<<x<<endl;//prints 1 or something else possibly, another thread could have changed x 
} 

int main(int argc, char**argv) 
{ 
    int x = 1; 
    test1(x); 
    //... 
    test2(x); 
    return 0; 
} 

Vì vậy, kết quả cuối cùng là bạn nhận được thay đổi ngay cả sau khi thông số được chuyển.

+0

"rất nguy hiểm khi trả lại một tham chiếu (const hay không)" - Tôi tò mò, làm cách nào để bạn trả về các giá trị nặng hơn? Có lẽ nhu cầu làm là một dấu hiệu của thiết kế kém, nhưng tôi có xu hướng trả về chuỗi bởi const ref. –

+0

@me - Tôi không nói dây là nặng, tôi chỉ muốn tránh các chi phí (phải thừa nhận có lẽ là nhỏ) của việc sao chép chúng xung quanh. –

+0

Bằng cách này bạn phải suy nghĩ về tuổi thọ của đối tượng. Điều đó có thể có giá trị đối với các kiểu dữ liệu phức tạp, nhưng không có giá trị nguyên gốc được sao chép với cùng chi phí như các tham chiếu. – sharptooth

5

Sự khác biệt chính giữa trả về giá trị và trả về tham chiếu const là bạn có thể const_cast tham chiếu đó và thay đổi giá trị.

Đây là ví dụ về thiết kế tồi và nỗ lực tạo thiết kế thông minh, nơi thiết kế dễ dàng và súc tích sẽ là quá đủ. Thay vì chỉ trả về một giá trị, tác giả làm cho độc giả của mã nghĩ rằng anh ta có ý định gì.

2

Tôi nghĩ loại mã này được viết đã hiểu sai khái niệm về tham chiếu và sử dụng nó cho mọi thứ kể cả các kiểu dữ liệu nguyên thủy. Tôi cũng đã nhìn thấy một số mã như thế này và không thể nhìn thấy bất kỳ lợi ích của việc này.

0

Không có điểm và lợi ích trừ

void MyClass::setFoo(const int foo) 
void MyClass::setFoo(const int& foo) 

như sau đó bạn sẽ không thể sử dụng lại 'foo' biến bên trong 'setFoo' thực hiện. Và tôi tin rằng 'int &' chỉ vì Guy chỉ quen với việc vượt qua tất cả mọi thứ bằng tham chiếu const và không có gì sai với điều đó.

4

Không có nhiều lợi ích. Tôi đã thấy điều này trong khuôn khổ hoặc vĩ mô tạo ra getters và setters trước. Mã vĩ mô không phân biệt giữa các kiểu nguyên thủy và không phải POD và chỉ sử dụng const type& trên bảng cho người định cư. Tôi nghi ngờ rằng đó là một vấn đề hiệu quả hoặc một sự hiểu lầm chính hãng; có thể đây là vấn đề nhất quán.

+0

+1 để gọi đó là vấn đề nhất quán. –

7

Với tôi, hãy chuyển một tham chiếu const cho nguyên thủy là một sai lầm.Bạn cần phải sửa đổi giá trị và trong trường hợp đó, bạn chuyển một tham chiếu không tham chiếu không phải là hoặc bạn chỉ cần truy cập vào giá trị và trong trường hợp đó, bạn chuyển const.

Tham chiếu Const chỉ nên được sử dụng cho các lớp phức tạp, khi sao chép các đối tượng có thể là vấn đề hiệu suất. Trong trường hợp nguyên thủy, trừ khi bạn cần sửa đổi giá trị của biến, bạn không nên vượt qua tham chiếu . Lý do là tài liệu tham khảo mất thời gian tính toán hơn phi tài liệu tham khảo, vì với sự tham khảo , chương trình cần phải nhìn lên trong một bảng để tìm ra địa chỉ của đối tượng. Khi thời gian tra cứu này ngắn hơn thời gian sao chép, tham chiếu là một cải tiến.

Nói chung, intsđịa chỉ có cùng độ dài byte trong triển khai cấp thấp. Vì vậy, thời gian sao chép int làm giá trị trả về cho hàm tương đương với thời gian sao chép địa chỉ . Nhưng trong trường hợp int được trả về, không có tra cứu nào được thực hiện, do đó hiệu suất được tăng lên.