استنادا إلى التعليقات
habr.com/en/post/460831/#comment_20416435 في
المنشور التالي والمناقشة التي بدأت هناك ، فإن المقالة حول كيفية تمرير الحجج بشكل صحيح إلى المُنشئ أو المقيد لن تعيق Habré. يحتوي StackOverflow على الكثير من المواد المماثلة ، لكنني لا أتذكر شيئًا هنا.
لأن المثال في هذه المقالة صحيح تمامًا ، ومؤلف المقال صحيح تمامًا. هنا مثال:
يسمح لك هذا الرمز بتغطية جميع الخيارات الممكنة (جيدًا تقريبًا) لاستخدام الفئة:
std::string first{"abc"}, last{"def"}; person p1{first, last};
قارن مع الطريقة القديمة ، عندما يتم تمريرها بواسطة const &: إنها بالتأكيد أسوأ ، لأنها تستبعد الخيار (3):
البديل مع && هو أيضًا أسوأ ، ولكن في الاتجاه المعاكس:
إذا لم تكن خائفًا من حدوث انفجار اندماجي ، فيمكنك إعطاء فرصة لـ && (لكن لماذا؟ لن يكون هناك مكسب حقيقي في السرعة ، لا يتوقف المحسن عن التجميد):
أو نفس الشيء ، فقط مع القوالب (ولكن مرة أخرى ، لماذا؟):
حتى لو لم يكن لديك std :: string ، لكن بعض العناصر من صفك الكبير المكتوب ، وتريد أن ينقلها الناس (وليس نسخًا) ، فمن الأفضل في هذه الحالة منع المُنشئ من النسخ من هذه الفئة الكبيرة بدلاً من تمريرها في كل مكان بواسطة &&. هذا أكثر موثوقية ، والكود أقصر.
أخيرًا ، هناك خياران حول كيفية القيام بما يلي:
وهكذا لا:
لماذا يحدث هذا ، ما هو المبدأ الأساسي؟ إنها بسيطة: كقاعدة ، يجب أن يمتلك خصائصه.
إذا كان الكائن لا يريد امتلاك شيء ما ، فيمكنه عندئذٍ امتلاك Shared_ptr لهذا "الشيء". بالمناسبة ، في هذه الحالة ، يجب أيضًا تمرير_تحديد_المشترك بالقيمة ، وليس بواسطة رابط ثابت - لا يوجد فرق مع المثال الأول في بداية المقال:
يرجى ملاحظة أن: std :: move for shared_ptr قانوني تمامًا ، فهو يزيل الحمل الزائد لقفل عداد ارتباط Shared_ptr في الذاكرة (مئات دورات وحدة المعالجة المركزية) وزيادة هذه البيانات. لا يؤثر على عمر الكائن والروابط الأخرى به. لكن (X) يمكن القيام به ، بالطبع ، فقط إذا لم تعد هناك حاجة إلى الرابط psh في الكود أدناه.
الأخلاقية: لا تستخدم const & بشكل عام. انظر وفقا للظروف.
PS
استخدم {} بدلاً من () عند تمرير معلمات المنشئ. عصري ، شبابي.
PPS
في الختام ، هناك شيء آخر: std :: move () في الواقع لا يحرك أي شيء ويترجم في حد ذاته إلى تعليمات المجمّع صفر. كل ما تفعله std :: move () هو وضع "ملصق لاصق" خاص على الرابط ، وتحويله إلى مرجع && - rvalue. علاوة على ذلك ، من الممكن مع هذه التسمية أن "تقوم" بمطابقة نوع معلمة الوظيفة بشكل منفصل (على سبيل المثال ، أن يكون هناك حمل زائد لوحدة منفصلة للمعلمة && - ومنفصل لـ & -المعلمة). معنى العلامة && - هو تمكين رمز الاتصال لإخبار ما يسمى: "إذا أردت ، يمكنك أن تأكل القيمة من هذا الرابط ، لم أعد بحاجة إليها ؛ ولكن فقط إذا كنت تأكل ، اترك العظام ، فأنا لا أزال بحاجة إلى استدعاء المدمر للهيكل العظمي المتبقي ". مع نفس النجاح ، سيكون من الممكن نقل الارتباطات العادية & -links (يمكنك أيضًا استخدام الكائن "للأكل") ، ولكن مع && دلالات ، لأن لن تخلط بين: حيث يمكنك أن تأكل ، وأين يمكنك أن تشتم فقط.
في هذا الصدد ، يجب التعرف على الاسم std :: move () على أنه غير ناجح للغاية. سيكون من الصحيح أن نسميها std :: eat_me_if_you_want () أو std :: bon_appetit (). لكن الأمراض المنقولة جنسيا :: move () أقصر.