Tôi đang học C ++ và cố gắng tránh mắc phải những thói quen xấu. Theo những gì tôi hiểu, clang-slim chứa nhiều "phương pháp hay nhất" và tôi cố gắng tuân theo chúng tốt nhất có thể (mặc dù tôi không nhất thiết phải hiểu tại sao chúng được coi là tốt), nhưng tôi không chắc liệu mình có hiểu những gì được đề xuất ở đây.
Tôi đã sử dụng lớp này từ hướng dẫn:
class Creature
{
private:
std::string m_name;
public:
Creature(const std::string &name)
: m_name{name}
{
}
};
Điều này dẫn đến một gợi ý từ clang-slim rằng tôi nên chuyển theo giá trị thay vì tham chiếu và sử dụng std::move. Nếu tôi làm, tôi nhận được gợi ý để làm cho namemột tài liệu tham khảo (để đảm bảo nó không được sao chép mỗi lần) và cảnh báo rằng std::movesẽ không có bất kỳ tác vì namelà một constvì vậy tôi nên loại bỏ nó.
Cách duy nhất tôi không nhận được cảnh báo là xóa consthoàn toàn:
Creature(std::string name)
: m_name{std::move(name)}
{
}
Điều này có vẻ hợp lý, vì lợi ích duy nhất của nó constlà ngăn chặn sự xáo trộn với chuỗi ban đầu (điều này không xảy ra vì tôi đã chuyển theo giá trị). Nhưng tôi đọc trên CPlusPlus.com :
Mặc dù lưu ý rằng -trong thư viện chuẩn- move ngụ ý rằng đối tượng được chuyển đến được để ở trạng thái hợp lệ nhưng không xác định. Có nghĩa là, sau một thao tác như vậy, giá trị của đối tượng được chuyển từ chỉ nên bị hủy hoặc gán một giá trị mới; truy cập nó nếu không sẽ mang lại một giá trị không xác định.
Bây giờ hãy tưởng tượng mã này:
std::string nameString("Alex");
Creature c(nameString);
Bởi vì nameStringđược truyền theo giá trị, std::movesẽ chỉ làm mất hiệu lực namebên trong hàm tạo và không chạm vào chuỗi ban đầu. Nhưng những lợi thế của điều này là gì? Có vẻ như nội dung chỉ được sao chép một lần - nếu tôi chuyển qua tham chiếu khi tôi gọi m_name{name}, nếu tôi chuyển theo giá trị khi tôi chuyển nó (và sau đó nó được di chuyển). Tôi hiểu rằng điều này tốt hơn là chuyển theo giá trị và không sử dụng std::move(vì nó được sao chép hai lần).
Vì vậy, hai câu hỏi:
- Tôi đã hiểu đúng những gì đang xảy ra ở đây?
- Có bất kỳ lợi ích nào của việc sử dụng
std::movechuyển qua tham chiếu và chỉ gọim_name{name}không?
std::string_viewvà cả SSO.
clang-tidylà một cách tuyệt vời để khiến bản thân bị ám ảnh bởi những kích thích vi mô không cần thiết với chi phí là khả năng đọc được. Câu hỏi cần đặt ra ở đây, trước bất kỳ điều gì khác, là chúng ta thực sự gọi hàm Creaturetạo bao nhiêu lần .
Creature c("John");tạo thêm một bản sao