سؤال

هل هناك أي سبب وجيه لعدم صلاحية مجموعة فارغة من الأقواس المستديرة (الأقواس) لاستدعاء المُنشئ الافتراضي في 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top