W tej chwili uczę się C ++ i staram się unikać złych nawyków. Z tego, co rozumiem, clang-tidy zawiera wiele „najlepszych praktyk” i staram się ich trzymać jak najlepiej (chociaż niekoniecznie rozumiem, dlaczego są jeszcze uważane za dobre), ale nie jestem pewien, czy zrozumieć, co jest tutaj zalecane.
Użyłem tej klasy z samouczka:
class Creature
{
private:
std::string m_name;
public:
Creature(const std::string &name)
: m_name{name}
{
}
};
Prowadzi to do sugestii ze strony clang-tidy, że powinienem przekazywać wartości zamiast odniesienia i używania std::move. Jeśli to zrobię, namepojawia się sugestia, aby zrobić odniesienie (aby upewnić się, że nie zostanie skopiowana za każdym razem) i ostrzeżenie, std::movektóre nie będzie miało żadnego efektu, ponieważ namejest consttak, więc powinienem je usunąć.
Jedynym sposobem, w jaki nie otrzymuję ostrzeżenia, jest constcałkowite usunięcie :
Creature(std::string name)
: m_name{std::move(name)}
{
}
Wydaje się to logiczne, ponieważ jedyną korzyścią constbyło zapobieganie pomieszaniu z oryginalnym ciągiem (co nie ma miejsca, ponieważ przekazałem wartość). Ale czytałem na CPlusPlus.com :
Chociaż należy zauważyć, że -w standardowej bibliotece-przeniesienie oznacza, że obiekt przeniesiony-z pozostaje w prawidłowym, ale nieokreślonym stanie. Co oznacza, że po takiej operacji wartość przenoszonego obiektu powinna zostać jedynie zniszczona lub przypisana nowa wartość; dostęp do niego w przeciwnym razie daje nieokreśloną wartość.
Teraz wyobraź sobie ten kod:
std::string nameString("Alex");
Creature c(nameString);
Ponieważ nameStringzostanie przekazany przez wartość, std::moveunieważni tylko namewewnątrz konstruktora i nie dotknie oryginalnego ciągu. Ale jakie są z tego zalety? Wygląda na to, że treść jest kopiowana tylko raz - jeśli przekażę przez odwołanie, gdy wywołuję m_name{name}, jeśli przekażę wartość, gdy ją przekażę (a następnie zostanie przeniesiona). Rozumiem, że jest to lepsze niż przekazywanie wartości i nie używanie std::move(ponieważ jest dwukrotnie kopiowane).
Więc dwa pytania:
- Czy dobrze zrozumiałem, co się tutaj dzieje?
- Czy jest jakaś korzyść z używania
std::moveprzekazywania przez referencję i po prostu dzwoniącm_name{name}?
Creature c("John");tworzy dodatkową kopię