التهيئة المرجعية في C ++
-
22-09-2019 - |
سؤال
هل يمكن لأي شخص أن يشرح لي لماذا يوجد فرق بين هذين البيانين؟
class A{};
const A& a = A(); // correct
A& b = A(); // wrong
تقول تهيئة غير صالحة للمرجع غير الممتاز للنوع A&
من نوع مؤقت A
لماذا const
مسألة هنا؟
المحلول
يجب تهيئة المراجع غير الممتدة مع قيم L. إذا تمكنت من تهيئتها مع المنشأة ، فماذا سيفعل ما يلي؟
int& foo = 5;
foo = 6; // ?!
const
المراجع لديها خاصية خاصة أنها تمدد عمر الحكم ، وبما أنها كذلك const
, ، لا يوجد أي احتمال أنك ستحاول تعديل شيء لا يجلس في الذاكرة. فمثلا:
const int& foo = 5;
foo = 6; // not allowed, because foo is const.
تذكر أن المراجع يجب أن تشير إلى شيء ما ، وليس فقط المتغيرات المؤقتة. على سبيل المثال ، ما يلي صالح:
int foo = 5;
int& bar = foo;
bar = 6;
assert(foo == 6);
نصائح أخرى
المصطلحات في هذا الأمر مربك بعض الشيء. قد ترغب في البحث عنها قليلاً. ها هي الجواب القصير على الرغم من:
تقوم بتعيين كائن مؤقت (نتيجة استدعاء مُنشئ الفئة) إلى متغير. كائن مؤقت هو قيمة r. لا يمكنك تعيين قيمة R إلى مرجع غير مؤهل.
يُسمح لك بتعيين قيمة R إلى مرجع const ، على الرغم من أن الأساس المنطقي للسماح بأنه غامض إلى حد ما.
في لغة C ++ ، من غير القانوني إرفاق إشارة غير محتملة إلى RValue ، في حين أنه من الجيد تمامًا إرفاق إشارة const إلى rvalue. على سبيل المثال ، هذا قانوني
const int& r = 5;
في حين أن هذا ليس كذلك
int &r = 5; // ERROR
كائن مؤقت من النوع A
عاد بالتعبير A()
هو rvalue ، لذلك تنطبق القاعدة أعلاه في قضيتك كذلك.
للحصول على علامة مؤقت/rvalue ، يمكنك فقط الحصول على مرجع const.
يمكن أن يكون لديك إشارة غير محتملة إلى Lvalue غير مؤقت.
A a;
A& b = a;
أعتقد أن السبب وراء تعزيز حقيقة أن rvalue مؤقت لأن هناك القليل من القيمة في القدرة على تعديل شيء يختفي للحظات.
لأن المعيار يقول ذلك:
§8.5.3.5 ... وإلا ، يجب أن يكون المرجع إشارة LVALUE إلى نوع const غير متقلبة ...
ومع ذلك ، إذا كنت تريدها كثيرًا ، فيمكنك الحصول عليها:
#include <iostream>
int main()
{
const int & cr=5;
int & r=const_cast<int &>(cr);
r=6;
std::cout<<r;
}
// outputs 6 with c++/clang++, Debian 8, amd64
لكن كن على دراية بأن CR الثابت المفترض لم يعد كذلك ، وأنك تتحمل سلوكًا غير محدد. (§1.9 (4))
كما اقترح الكود أعلاه ، لا يوجد سبب تقني للفرق. بدلاً من ذلك ، كان لدى المصممين كوابيس حول ما سيفعله المستخدمون مع الإشارات غير المؤسسة إلى المنشأة.