Trả về tham chiếu hoặc tham chiếu const không có chênh lệch tốc độ - cả hai đều rất nhanh vì chúng chỉ trả lại tham chiếu đến đối tượng gốc, không có sự sao chép nào.
Một đối tượng được trả về bởi tham chiếu (không phải) có thể được sửa đổi thông qua tham chiếu đó. Trong ví dụ cụ thể của bạn, mString
là công khai, vì vậy, nó có thể được sửa đổi (và trực tiếp). Tuy nhiên, cách tiếp cận thông thường với getters và setters (và lý do chính để giới thiệu) là đóng gói - bạn chỉ cho phép truy cập vào các thành viên dữ liệu của bạn thông qua getter/setter, để bạn có thể phát hiện các giá trị không hợp lệ. nói chung giữ cho các chi tiết thực hiện của lớp ẩn bên trong nó. Vì vậy, getters thường trở lại bằng tham chiếu const hoặc theo giá trị.
Tuy nhiên, nếu bạn quay trở lại tham chiếu const, nó liên kết bạn với luôn luôn giữ một phiên bản std::string
trong lớp học của bạn để sao lưu tham chiếu. Đó là, ngay cả khi sau này bạn muốn thiết kế lại lớp học của bạn để nó tính toán chuỗi trên bay trong getter thay vì lưu trữ nó trong nội bộ, bạn không thể. Bạn sẽ phải thay đổi giao diện công cộng của bạn cùng một lúc, có thể phá vỡ mã bằng cách sử dụng lớp.Ví dụ, miễn là bạn quay trở lại bởi const-tài liệu tham khảo, đây là mã hoàn toàn hợp lệ:
const std::string *result = &aSample.Get();
Mã này sẽ đương nhiên
tạo ra một con trỏ tòn ten
không còn biên dịch nếu Get()
được thay đổi để trở lại theo giá trị thay vì tham chiếu const. (nhờ Steve Jessop sửa lỗi cho tôi)
Tóm lại, cách tiếp cận tôi cần thực hiện là thực hiện mString
riêng tư. Get()
có thể trả về theo giá trị hoặc bằng tham chiếu const, tùy thuộc vào mức độ chắc chắn của bạn mà bạn sẽ luôn có một chuỗi được lưu trữ. Lớp sau đó sẽ trông như thế này:
class sample
{
std::string mString;
public:
void Set(const std::string &s)
{
mString = s;
}
std::string Get() const
{
return mString;
}
};
"Mã này tất nhiên sẽ tạo ra một con trỏ lơ lửng nếu Get() được thay đổi để trả về giá trị thay vì tham chiếu const." - không có nó sẽ không, nó sẽ ngừng biên dịch ("không thể lấy địa chỉ tạm thời"). Mà là tốt hơn so với biên dịch nhưng với UB. Trên thực tế nó * có thể * biên dịch do một phần mở rộng, nhưng tôi không nghĩ rằng đó là một phần mở rộng phổ biến và tiêu chuẩn vẫn gọi cho một chẩn đoán để người sử dụng nên được ít nhất là cảnh báo. –
@SteveJessop Cảm ơn, tôi đã sửa câu trả lời. – Angew