المنشئ الافتراضي مع أقواس فارغة
-
05-07-2019 - |
سؤال
هل هناك أي سبب وجيه لعدم صلاحية مجموعة فارغة من الأقواس المستديرة (الأقواس) لاستدعاء المُنشئ الافتراضي في C++؟
MyObject object; // ok - default ctor
MyObject object(blah); // ok
MyObject object(); // error
يبدو أنني أكتب "()" تلقائيًا في كل مرة.هل هناك سبب وجيه لعدم السماح بذلك؟
المحلول
التحليل الأكثر إرباكًا
يرتبط هذا بما يُعرف بـ "التحليل الأكثر إرباكًا لـ C++".في الأساس، أي شيء يمكن للمترجم تفسيره على أنه إعلان دالة سيتم تفسيره على أنه إعلان دالة.
مثال آخر لنفس المشكلة:
std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());
v
يتم تفسيره على أنه إعلان للوظيفة بمعلمتين.
الحل البديل هو إضافة زوج آخر من الأقواس:
std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());
أو، إذا كان لديك C++ 11 وتهيئة القائمة (المعروفة أيضًا باسم التهيئة الموحدة):
std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};
مع هذا، لا توجد طريقة يمكن تفسيرها على أنها إعلان دالة.
نصائح أخرى
ولأنه هو تعامل على أنها إعلان عن وظيفة:
int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
ويستخدم نفس بناء الجملة للإعلان وظيفة - على سبيل المثال وظيفة object
، مع أية معلمات والعودة MyObject
ولأن المترجم يعتقد أنه هو الإعلان عن وظيفة يأخذ بدون وسائط وإرجاع مثيل MyObject.
وأعتقد، أن المترجم لا يعرف ما اذا كان هذا البيان:
<اقتباس فقرة>وMyObject الكائن ()؛
اقتباس فقرة>ودعوة منشئ أو نموذج وظيفة إعلان وظيفة المسمى <م> الكائن م> مع نوع الإرجاع <م> MyObject م> وأية معلمات.
ويمكنك أيضا استخدام طريقة أكثر مطول البناء:
MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);
في C ++ 0X هذا يسمح أيضا لauto
:
auto object1 = MyObject();
auto object2 = MyObject(object1);
وكما ذكر عدة مرات، انها الإعلان. انها بهذه الطريقة من أجل التوافق مع الإصدارات السابقة. واحدة من العديد من مناطق C ++ التي هي أبله / تتعارض / مؤلمة / وهمية بسبب إرثها.
ومن n4296 [dcl.init]:
<اقتباس فقرة> [ملاحظة:
منذ ()
لا يسمح به بناء الجملة من أجل <م> مهيئ م>،
X a();
ليس إعلان كائن <م> م> من الفئة X، ولكن
إعلان وظيفة <م> م> عدم اتخاذ أي حجة والعودة إلى عاشرا
شكل () مسموح في بعض السياقات التهيئة الأخرى (5.3.4،
5.2.3، 12.6.2).
-end ملاحظة]
وكما قال آخرون، بل هو إعلان وظيفة. منذ C ++ 11 يمكنك استخدام هدفين التهيئة إذا كنت بحاجة لرؤية فارغة <م> شيء م> أن يقول صراحة لكم ان يستخدم منشئ افتراضي.
Jedi luke{}; //default constructor