рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдФрд░ рд╕реЗрдЯрд░ рдХреЗ рдорд╛рди рд╕реЗ рдЧреБрдЬрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реИрдХреНрд╖рд┐рдХ рдХрд╛рд░реНрдпрдХреНрд░рдо (рдЖрдзреБрдирд┐рдХ C ++, рдЙрджрд╛рд╣рд░рдг)

рдЕрдЧрд▓реА рдкреЛрд╕реНрдЯ рдореЗрдВ habr.com/en/post/460831/#comment_20416435 рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдФрд░ рд╡рд╣рд╛рдВ рд╕рд╛рдордиреЗ рдЖрдИ рдЪрд░реНрдЪрд╛ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдХрд┐ рдХреИрд╕реЗ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдпрд╛ рд╕реЗрдЯрд░ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦ Habr├й рдореЗрдВ рдмрд╛рдзрд╛ рдирд╣реАрдВ рдмрдиреЗрдЧрд╛ред StackOverflow рдореЗрдВ рдмрд╣реБрдд рд╕реА рд╕рдорд╛рди рд╕рд╛рдордЧреНрд░реА рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрд╣рд╛рдБ рдХреБрдЫ рдпрд╛рдж рдирд╣реАрдВ рд╣реИред

рдХреНрдпреЛрдВрдХрд┐ рдЙрд╕ рд▓реЗрдЦ рдореЗрдВ рдЙрджрд╛рд╣рд░рдг рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рд╣реА рд╣реИ, рдФрд░ рд▓реЗрдЦ рдХрд╛ рд▓реЗрдЦрдХ рдмрд┐рд▓реНрдХреБрд▓ рд╕рд╣реА рд╣реИред рдпрд╣рд╛рдБ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:

// . struct person { person(std::string first_name, std::string last_name) : first_name{std::move(first_name)} //  , last_name{std::move(last_name)} // std::move  ! {} private: std::string first_name; std::string last_name; }; 

рдРрд╕рд╛ рдХреЛрдб рдЖрдкрдХреЛ рдХрдХреНрд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА (рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рд▓рдЧрднрдЧ рд╕рднреА) рд╕рдВрднрд╛рд╡рд┐рдд рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ:

 std::string first{"abc"}, last{"def"}; person p1{first, last}; // (1)    person p2{std::move(first), last}; // !!!    person p2{std::move(first), std::move(last)}; // (3)   person p3{"x", "y"}; //   

рдкреБрд░рд╛рдиреА рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░реЗрдВ, рдЬрдм рдХрдмреНрдЬ рд╕реЗ рдЧреБрдЬрд░рд╛ рдФрд░: рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЦрд░рд╛рдм рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╡рд┐рдХрд▓реНрдк (3) рдХреЛ рдмрд╛рд╣рд░ рдХрд░рддрд╛ рд╣реИ:

 // . struct person { person(const std::string& first_name, const std::string& last_name) : first_name{first_name} , last_name{last_name} {} private: std::string first_name; std::string last_name; }; std::string first{"abc"}, last{"def"}; person p1{first, last}; //  ,    //      ,  first  last    // ?         //   0 !  const& . 

&& рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд┐рдХрд▓реНрдк рднреА рдмрджрддрд░ рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВ:

 // . struct person { person(std::string&& first_name, std::string&& last_name) : first_name{std::move(first_name)} , last_name{std::move(last_name)} {} private: std::string first_name; std::string last_name; }; std::string first{"abc"}, last{"def"}; person p1{std::move(first), std::move(last)}; //  //       ,    &&  : person p2{std::string{first}, std::string{last}}; // FOOOO 

рдпрджрд┐ рдЖрдк рдПрдХ рджрд╣рдирд╢реАрд▓ рд╡рд┐рд╕реНрдлреЛрдЯ рд╕реЗ рдбрд░рддреЗ рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдЖрдк && рдХреЛ рдПрдХ рдореМрдХрд╛ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ (рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВ? рдЧрддрд┐ рдореЗрдВ рдХреЛрдИ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд▓рд╛рдн рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝рд░ рдмрдВрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ):

 //   . struct person { person(std::string&& first_name, std::string&& last_name) : first_name{std::move(first_name)} , last_name{std::move(last_name)} {} person(const std::string& first_name, std::string&& last_name) : first_name{first_name} , last_name{std::move(last_name)} {} person(std::string&& first_name, const std::string& last_name) : first_name{std::move(first_name)} , last_name{last_name} {} person(const std::string& first_name, const std::string& last_name) : first_name{first_name} , last_name{last_name} {} private: std::string first_name; std::string last_name; }; 

рдпрд╛ рдПрдХ рд╣реА рдмрд╛рдд, рдХреЗрд╡рд▓ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХреЗ рд╕рд╛рде (рд▓реЗрдХрд┐рди рдлрд┐рд░ рд╕реЗ, рдХреНрдпреЛрдВ?):

 //     (   ),      . struct person { template <typename T1, typename T2> person(T1&& first_name, T2&& last_name) : first_name{std::forward<T1>(first_name)} , last_name{std::forward<T2>(last_name)} {} private: std::string first_name; std::string last_name; }; 

рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдЧрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ std :: string рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдкрдХреА рдЦреБрдж рдХреА рд▓рд┐рдЦреА рд╣реБрдИ рдмрдбрд╝реА рдХрдХреНрд╖рд╛ рдХреА рдХреБрдЫ рд╡рд╕реНрддреБ, рдФрд░ рдЖрдк рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рд▓реЛрдЧ рдЗрд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ (рдФрд░ рдХреЙрдкреА рди рдХрд░реЗрдВ), рддреЛ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдЗрд╕ рдмрдбрд╝реЗ рд╡рд░реНрдЧ рд╕реЗ рдХреЙрдкреА рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдмреЗрд╣рддрд░ рд╣реИ рдХрд┐ рдЗрд╕реЗ рд╣рд░ рдЬрдЧрд╣ рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред рджреНрд╡рд╛рд░рд╛ &&ред рдпрд╣ рдЕрдзрд┐рдХ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд╣реИ, рдФрд░ рдХреЛрдб рдЫреЛрдЯрд╛ рд╣реИред

рдЕрдВрдд рдореЗрдВ, рдХреИрд╕реЗ рдХрд╛рдо рди рдХрд░реЗрдВ, рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рд╡рд┐рдХрд▓реНрдк:

 // . struct person { person(const std::string& first_name, const std::string& last_name) : first_name{first_name} , last_name{last_name} {} private: //   :  ,     //     const std::string& first_name; const std::string& last_name; }; person p{"x", "y"}; // --,  

рдФрд░ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ:

 // . struct person { person(std::string& first_name, std::string& last_name) : first_name{first_name} , last_name{last_name} {} private: //   ,      shared_ptr: //  ,   std::string& first_name; std::string& last_name; }; 

рдРрд╕рд╛ рдХреНрдпреЛрдВ рд╣реЛ рд░рд╣рд╛ рд╣реИ, рдореВрд▓ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреНрдпрд╛ рд╣реИ? рдпрд╣ рд╕рд░рд▓ рд╣реИ: рдПрдХ рд╡рд╕реНрддреБ, рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдЗрд╕рдХреЗ рдЧреБрдгреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдпрджрд┐ рд╡рд╕реНрддреБ рдХреБрдЫ рдЦреБрдж рдХрд░рдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддреА рд╣реИ, рддреЛ рд╡рд╣ рдЗрд╕ "рдХреБрдЫ" рдХреЗ рд▓рд┐рдП рдЦреБрдж рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░ рд╕рдХрддреА рд╣реИред рд╡реИрд╕реЗ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ share_ptr рдХреЛ рднреА рдореВрд▓реНрдп рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдФрд░ рдирд┐рд░рдВрддрд░ рд▓рд┐рдВрдХ рджреНрд╡рд╛рд░рд╛ рдирд╣реАрдВ - рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдмрд╣реБрдд рдкрд╣рд▓реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдХреЛрдИ рдЕрдВрддрд░ рдирд╣реАрдВ рд╣реИ:

 //  (  ). struct person { person(std::shared_ptr<portfolio> pf) : pf{std::move(pf)} // std::move     {} private: std::shared_ptr<portfolio> pf; }; auto psh = std::make_shared<portfolio>("xxx", "yyy", "zzz"); ... person p1{psh}; person p2{std::move(psh)}; // (X)  ,  psh    

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ: std :: share_ptr рдХреЗ рд▓рд┐рдП рдХрджрдо рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдиреВрдиреА рд╣реИ, рдпрд╣ рдореЗрдореЛрд░реА рдореЗрдВ рд╢реЗрдпрд░реНрдб_ptr рд▓рд┐рдВрдХ рдХрд╛рдЙрдВрдЯрд░ (CPU рдХреЗ рд╕реИрдХрдбрд╝реЛрдВ) рдФрд░ рдЙрд╕рдХреЗ рдЗрдВрдХреНрд░реАрдореЗрдВрдЯ рдХреЛ рд▓реЙрдХ рдХрд░рдиреЗ рдХреЗ рдУрд╡рд░рд╣реЗрдб рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╡рд╕реНрддреБ рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рдФрд░ рдЙрд╕рд╕реЗ рдЬреБрдбрд╝реА рдЕрдиреНрдп рдХрдбрд╝рд┐рдпреЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди (рдПрдХреНрд╕), рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдЕрдЧрд░ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХреЛрдб рдореЗрдВ psh рд▓рд┐рдВрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

Moral: рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ const & рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВред рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рджреЗрдЦреЛред

рдкреБрдирд╢реНрдЪ
рдирд┐рд░реНрдорд╛рдг рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд░рд┐рдд рдХрд░рддреЗ рд╕рдордп () рдХреЗ рдмрдЬрд╛рдп {} рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рдлреИрд╢рдиреЗрдмрд▓, рдЖрдзреБрдирд┐рдХ, рдпреБрд╡рд╛ред

рдкреА рдкреА рдПрд╕
рдЕрдВрдд рдореЗрдВ, рдПрдХ рдФрд░ рдмрд╛рдд: std :: move () рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреБрдЫ рднреА рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рд╢реВрдиреНрдп рдХреЛрдбрд╛рдВрддрд░рдХ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░рддрд╛ рд╣реИред рд╕рднреА рдХрд┐ std :: move () рд▓рд┐рдВрдХ рдкрд░ рдПрдХ рд╡рд┐рд╢реЗрд╖ "рдЪрд┐рдкрдЪрд┐рдкрд╛ рд▓реЗрдмрд▓" рд▓рдЧрд╛рдирд╛ рд╣реИ, рдЗрд╕реЗ рдПрдХ && - rvalue рд╕рдиреНрджрд░реНрдн рдореЗрдВ рдмрджрд▓рдирд╛ рд╣реИред рдФрд░ рдЖрдЧреЗ рдЗрд╕ рд▓реЗрдмрд▓ рдХреЗ рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЛ "рдореЗрд▓" рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, && - рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдлрд╝рдВрдХреНрд╢рди рдЕрдзрд┐рднрд╛рд░ рдФрд░ -parameter рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ)ред && - рд▓реЗрдмрд▓ рдХрд╛ рдЕрд░реНрде рдХреЙрд▓рд┐рдВрдЧ рдХреЛрдб рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдХреНрд╖рдо рдХрд░рдирд╛ рд╣реИ: "рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ, рддреЛ рдЖрдк рдЗрд╕ рд▓рд┐рдВрдХ рд╕реЗ рдореВрд▓реНрдп рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдореБрдЭреЗ рдЕрдм рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ; рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдЕрдЧрд░ рдЖрдк рдЦрд╛рддреЗ рд╣реИрдВ, рд╣рдбреНрдбрд┐рдпреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рдЕрднреА рднреА рд╢реЗрд╖ рдХрдВрдХрд╛рд▓ рдХреЗ рд▓рд┐рдП рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред " рдЙрд╕реА рд╕рдлрд▓рддрд╛ рдХреЗ рд╕рд╛рде, рд╕рд╛рдзрд╛рд░рдг & -рд▓рд┐рдВрдХреНрд╕ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ (рдЖрдк рд╡рд╕реНрддреБ рдХрд╛ рдЙрдкрдпреЛрдЧ "рдЙрдиреНрд╣реЗрдВ рдЦрд╛рдиреЗ" рдХреЗ рд▓рд┐рдП рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ), рд▓реЗрдХрд┐рди && рд╢рдмреНрджрд╛рд░реНрде рдмреЗрд╣рддрд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдк рднреНрд░рдорд┐рдд рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ: рдЬрд╣рд╛рдВ рдЖрдк рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЬрд╣рд╛рдВ рдЖрдк рдХреЗрд╡рд▓ рдЧрдВрдз рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЗрд╕ рд╕рдВрдмрдВрдз рдореЗрдВ, рдирд╛рдо std :: move () рдХреЛ рдмреЗрд╣рдж рдЕрд╕рдлрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдиреНрдпрддрд╛ рджреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред рдЗрд╕реЗ std :: eat_me_if_you_want () рдпрд╛ std :: bon_appetit () рдХрд╣рдирд╛ рд╕рд╣реА рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди std :: Move () рдЫреЛрдЯрд╛ рд╣реИред

Source: https://habr.com/ru/post/hi460955/


All Articles