ฉันกำลังเรียนรู้ C ++ ในขณะนี้และพยายามหลีกเลี่ยงนิสัยที่ไม่ดี จากสิ่งที่ฉันเข้าใจเสียงดังเป็นระเบียบมี "แนวทางปฏิบัติที่ดีที่สุด" มากมายและฉันพยายามยึดมั่นในแนวทางปฏิบัติเหล่านี้ให้ดีที่สุด (แม้ว่าฉันจะไม่เข้าใจว่าเหตุใดจึงถือว่าดี) แต่ฉันไม่แน่ใจว่า เข้าใจสิ่งที่แนะนำที่นี่
ฉันใช้คลาสนี้จากบทช่วยสอน:
class Creature
{
private:
std::string m_name;
public:
Creature(const std::string &name)
: m_name{name}
{
}
};
std::move
นี้นำไปสู่ข้อเสนอแนะจากเสียงดังกราว-เป็นระเบียบเรียบร้อยที่ฉันควรจะผ่านค่าแทนการอ้างอิงและการใช้งาน ถ้าเป็นเช่นนั้นฉันจะได้รับคำแนะนำให้ทำการname
อ้างอิง (เพื่อให้แน่ใจว่าจะไม่มีการคัดลอกทุกครั้ง) และคำเตือนที่std::move
จะไม่มีผลใด ๆ เพราะname
เป็นconst
ดังนั้นฉันจึงควรลบออก
วิธีเดียวที่ฉันไม่ได้รับคำเตือนคือการลบconst
ทั้งหมด:
Creature(std::string name)
: m_name{std::move(name)}
{
}
ซึ่งดูเหมือนจะเป็นตรรกะเนื่องจากประโยชน์เพียงอย่างเดียวconst
คือการป้องกันไม่ให้ยุ่งกับสตริงเดิม (ซึ่งไม่ได้เกิดขึ้นเพราะฉันส่งผ่านค่า) แต่ฉันอ่านในCPlusPlus.com :
แม้ว่าโปรดทราบว่า -in การย้ายไลบรารีมาตรฐานหมายความว่าอ็อบเจ็กต์ที่ย้ายจากถูกปล่อยให้อยู่ในสถานะที่ถูกต้อง แต่ไม่ได้ระบุ ซึ่งหมายความว่าหลังจากการดำเนินการดังกล่าวมูลค่าของวัตถุที่ย้ายจากควรถูกทำลายหรือกำหนดค่าใหม่เท่านั้น การเข้าถึงมิฉะนั้นจะให้ค่าที่ไม่ระบุ
ลองนึกภาพรหัสนี้:
std::string nameString("Alex");
Creature c(nameString);
เนื่องจากnameString
ได้รับการส่งผ่านค่าstd::move
จะทำให้ไม่ถูกต้องname
ภายในตัวสร้างและไม่สัมผัสสตริงเดิม แต่ข้อดีของสิ่งนี้คืออะไร? ดูเหมือนว่าเนื้อหาจะถูกคัดลอกเพียงครั้งเดียว - หากฉันผ่านการอ้างอิงเมื่อฉันโทรm_name{name}
ถ้าฉันส่งผ่านค่าเมื่อฉันส่งผ่าน (แล้วมันจะถูกย้าย) ฉันเข้าใจว่าสิ่งนี้ดีกว่าการส่งผ่านค่าและไม่ใช้std::move
(เพราะถูกคัดลอกสองครั้ง)
คำถามสองข้อ:
- ฉันเข้าใจถูกต้องหรือไม่ว่าเกิดอะไรขึ้นที่นี่?
- มีข้อดีของการใช้
std::move
over pass by reference และแค่โทรm_name{name}
?
clang-tidy
เป็นวิธีที่ดีในการทำให้ตัวเองหมกมุ่นอยู่กับการเพิ่มประสิทธิภาพขนาดเล็กที่ไม่จำเป็นโดยเสียค่าใช้จ่ายในการอ่าน คำถามที่จะถามที่นี่ก่อนสิ่งอื่นคือเราเรียกตัวสร้างจริงกี่ครั้ง Creature
Creature c("John");
ทำสำเนาเพิ่มเติม