عودة المراجع من أساليب C ++
-
02-10-2019 - |
سؤال
أيها الأصدقاء الأعزاء ، أشعر بالقلق إذا كنت أستفيد بشكل سيء للمراجع في C ++ في الطريقة التالية تشكو GCC من تحذير "إلى المتغير المحلي" أنا "عاد"
MatrizEsparsa& MatrizEsparsa::operator+(MatrizEsparsa& outra){
MatrizEsparsa me(outra.linhas(),outra.colunas());
return me;
}
ولكن ، مع التغييرات التالية يختفي التحذير:
MatrizEsparsa& MatrizEsparsa::operator+(MatrizEsparsa& outra){
MatrizEsparsa me(outra.linhas(),outra.colunas());
MatrizEsparsa &ref = me;
return ref;
}
هل الطريقة السابقة (إرجاع متغير "المرجع") صحيحة مقبولة؟
المحلول
رقم. ref
لا يزال يشير إلى me
والتي سيتم تدميرها في نهاية المكالمة.
يجب عليك إرجاع نسخة من نتيجتك (لا تربى عن طريق &
).
MatrizEsparsa MatrizEsparsa::operator+(const MatrizEsparsa& outra) const {
return MatrizEsparsa(outra.linhas(),outra.colunas());
}
لقد أضفت أيضًا اثنين const
المحددات (إلى المعلمة والطريقة) لأنني أشك outra
أو يجب تعديل مثيل الاتصال في هذه الحالة. (قد أكون مخطئًا ، ولكن بعد ذلك operator+
سيكون لها دلالي غريب)
من خلال القيام بما فعلته ، جعلت الرمز أكثر تعقيدًا. ربما كان المترجم مرتبكًا ولم يستطع تحذيرك من خطأك المحتمل.
عادة ، عندما يتعين عليك استخدام الحيل الذكية للقيام بأشياء بسيطة ، فهذا يعني أن هناك خطأ ما.
نصائح أخرى
أعتقد أنك تخطئ في المشغلين.
هناك 2:
struct Foo
{
Foo& operator+=(Foo const&);
Foo operator+(Foo const&) const;
};
كما لاحظت ، فإن الأول يعيد إشارة إلى نفسه ، والثاني لا.
أيضًا ، بشكل عام ، يجب كتابة الثانية كدالة مجانية.
Foo operator+(Foo const&, Foo const&);
يمكن أن يكون هذا آليًا ، لأنه مرهق ، باستخدام المعززات:
struct Foo: boost::addable<Foo>
{
Foo& operator+=(Foo const& rhs)
{
// add
return *this;
}
};
قليلا boost::addable
سيقوم السحر تلقائيًا بإنشاء ملف +
التنفيذ على أساس Foo::operator+=
.
هذا غير مقبول. إنها في الواقع نفس المشكلة: إرجاع مرجع غير مؤكد إلى كائن محلي سيتم تدميره بعد إعادة الطريقة.
لا ، يجب عليك إرجاع قيمة هنا ، من الناحية المثالية أ const
القيمة. انظر فعالة C ++ ، البند 21.
أقترح الواجهة التالية:
const MatrizEsparsa operator+(const MatrizEsparsa& left, const MatrizEsparsa& right);
لاحظ أن كل شيء إما const
مرجع أو const
القيمة. العودة أ const
القيمة ليست بنفس أهمية إرجاع القيمة أو إعلان المعلمات مثل const
المراجع ، لكن حجج سكوت مايرز أقنعتني ، على الرغم من أن لا أحد يتبعها.
لا يمكنك إرجاع المرجع لأن الكائن الذي تشير إليه سيتم تدميره خارج سيطرتك. إما أن نضع "ME" كمتغير عضو في MatrizesParsa بحيث يستمر بعد تنفيذ الوظيفة الأخرى لإرجاع مؤشر ، أو تعزيز Smart_Ptr ، الذي يشير إلى الكائن.
نظرًا لأن هذا هو مشغل + ، فربما تريد إرجاع قيمة بدلاً من إشارة إلى متغير داخلي إلى الوظيفة.