2011-12-22 27 views
7

Ví dụ:Những ảnh hưởng của việc sử dụng ký hiệu trước một tên hàm trong C++?

inline string &GetLabel() { 
     return m_Label; 
}; 

Trong đó m_Label là biến thành viên lớp riêng tư.

Cách tôi nghĩ rằng tôi hiểu nó, hàm này sẽ trả về tham chiếu đến biến m_Label. Điều gì sẽ là tác động của việc sử dụng điều này trong suốt chương trình của tôi và nó sẽ là một tốt hơn để chỉ trả lại giá trị, thay vì tham chiếu? Cảm ơn bạn!

Trả lời

6

Nó trả về một tham chiếu đến thành viên riêng tư.

Có rất nhiều trường hợp điều này là mong muốn, nhưng cần phải thận trọng.

IMO thường không phải là một ý tưởng tốt để trả lại một bản sao của một đối tượng nội bộ không phải là một loại tích phân, vì lý do hiệu suất tổng thể. Có, tôi biết, tối ưu hóa sớm là không tốt, nhưng điều này không thực sự tối ưu hóa, nó chỉ là một thực hành hiệu suất tốt cho phép người gọi để xác định các tác động hiệu suất; nếu nó muốn có một bản sao, nó có thể không khai báo biến mà nó gán nó làm tham chiếu.

Có 2 quy tắc chung của ngón tay cái tôi sử dụng ở đây:

1) Nếu bạn không muốn người gọi để có thể sửa đổi các đối tượng cá nhân trực tiếp, kê khai giá trị trả về là một tham chiếu const:

inline const string& GetLabel() const{ return m_Label; } 

2) Người gọi không bao giờ lưu trữ tham chiếu được trả về từ phương thức lớp, chỉ nên sử dụng cục bộ ở nơi đối tượng cha được bảo đảm nằm trong phạm vi.

Nếu vì một số lý do bạn cần người gọi để có thể lưu trữ một tham chiếu đến các đối tượng bên trong của bạn, hãy sử dụng con trỏ thông minh để thay thế.

11

Dấu và không phải trước tên hàm nhiều như sau khi loại trả về. nó trả về một tham chiếu đến một số string.

Ý nghĩa của việc này là người gọi hàm này có thể sửa đổi giá trị m_label thông qua tham chiếu. Mặt khác, nó tránh sao chép chuỗi. Bạn có thể muốn tham chiếu và chức năng là const, như vậy:

inline const string& GetLabel() const 
{ 
    return m_Label; 
} 

Tốt nhất của cả hai thế giới. Bạn tránh bản sao, nhưng người gọi không thể thay đổi đối tượng của bạn.

+0

Thật vậy, bạn có thể muốn _both_ các phiên bản const và không const. – ildjarn

+0

@ildjam Điều đó chỉ đúng một phần. Thông thường, bạn sẽ chỉ muốn cung cấp phiên bản const, trừ khi bạn có lý do muốn cho phép người gọi trực tiếp sửa đổi đối tượng. Nếu bạn cung cấp phiên bản không phải const, thì bạn cũng nên cung cấp phiên bản const, để bạn vẫn có thể truy cập chỉ đọc trong đó bạn có tham chiếu const đến đối tượng cha. – Gerald

+1

@Gerald: Xin lỗi, tôi nên làm rõ - ý tôi là, nếu bạn muốn phiên bản không const trả về một tham chiếu, thì bạn gần như chắc chắn cũng muốn có một phiên bản const. – ildjarn

1

Bạn là chính xác. Đó là một tham chiếu đến thành viên chuỗi.

Hàm ý sẽ là nếu người gọi đã chỉ định giá trị hoặc sửa đổi chuỗi trả về thì họ cũng sẽ sửa đổi biến thành viên. Nếu đây không phải là ý định bạn có thể muốn trả lại một bản sao theo giá trị để tránh phá vỡ đóng gói.

2

Trả về tham chiếu có nghĩa là mã gọi có thể sửa đổi giá trị của biến thành viên của bạn sau khi bạn quay trở lại. Điều đó rất nguy hiểm, trừ khi bạn dự định điều đó xảy ra.

Tốt hơn là tham chiếu const hoặc trả về theo giá trị (không có &).

2

Một ý nghĩa là nếu đối tượng kèm theo là destructed, tham chiếu trở nên không hợp lệ:

Object* o = new Object; 
string& label = o->GetLabel(); 
delete o; 
// label becomes a dangling reference here. 

hàm ý khác là một người gọi có thể sửa đổi các chuỗi. Bạn có thể khắc phục điều đó bằng cách trả lại tham chiếu const.

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