c++ شرح - لماذا يتصل المتجه الفارغ بمنشئ افتراضي من نوع القيمة؟




vector example (3)

باستخدام g ++ ، ألاحظ أن إنشاء متجه من الحجم صفر يستدعي منشئ نوع الكائن المعتمد في vector مرة واحدة. ومن ثم يتم حذفها. لماذا يحدث هذا؟

#include <iostream>
#include <vector>
using namespace std;

class s
{
    public:
    s() { cout << endl << "default s constructor" << endl; }
    ~s() { cout << endl << "default s destructor" << endl; }

};

int main()
{
    vector<s> v(0);
}

انتاج:

منشئ افتراضي

الافتراضي د destructor


Answers

لأنك بصراحة تمرر حجم أولي ، والذي يستدعي منشئ يحتوي على معلمة أخرى قيمته الافتراضية هي s() . فقط اترك خارج (0) (أي std::vector<s> v; ) ولن يحدث ذلك.

للتأكد من اكتمالها ، يحدد المعيار 23.2.4-2 المُنشئ الذي تتصل به على النحو التالي:

explicit vector(size_type n, const T& value = T() ,
const Allocator& = Allocator());

جانبًا (ذو صلة بـ C ++ 03 وليس C ++ 11)

هناك جانب سلوكي آخر مثير للاهتمام لهذا المنشئ يثير أيضًا رأسًا على SO بشكل دوري: فعندما يكون العدد الأولي للعناصر المطلوبة أقل من 0 ، فإنها تقوم بنسخ تلك العناصر من المعلمة النموذجية إلى المُنشئ:

  • كثيرًا ما يضع الأشخاص مُنشئًا افتراضيًا يترك المتغيرات الخاصة بالأعضاء غير مهيأة ، على أمل جعل vector(n) يكاد يكون بنفس سرعة تخصيص المخزن الحر الأساسي ، ولكن
  • لا يزال يُطلق على منشئ النسخ اسم "n" لنسخ محتوى "القمامة" الخاص بالكائن النموذجي في كل عنصر من العناصر المطلوبة

هذا له تكلفة أداء واضحة ولكن يمكن أيضاً تعطل التطبيق إذا تضمن محتوى القمامة على سبيل المثال المؤشرات التي يمكن فقط افتراض أن المنشئ نسخ صحيحة. وبالمثل ، فإنه من الخطورة للغاية أن push_back حتى على مثل هذا الكائن غير المهيأ ، حيث أنه يفتقر إلى القيمة الصحيحة للتغليف الدلالي ، ويمكن نسخه كتحويل متجه ، حيث يتم تنفيذ العمليات الخوارزمية مثل std::sort() على المتجهات وما إلى ذلك.


المنشئ الفعلي الذي تتصل به هو (من cplusplus.com):

explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );

لذلك حتى لو قمت بتحديد الحجم فقط ، يتم إنشاء كائن T جديد للمعلمة الثانية ، وبالتالي سيتم تدميره أيضًا في نهاية المُنشئ.


الجواب البسيط: من الناحية التقنية

اجابة طويلة:

لا.
لكن بناء الجملة الذي تستخدمه لتهيئتها يجعلها تبدو وكأنها يتم بناؤها بواسطة مُنشئ افتراضي أو مُنشئ نسخ افتراضي.

int x(5);  // Looks like a constructor. Behaves like one: x is initialized.
int y();   // Fail. Actually a function declaration.
// BUT
int z = int(); // Looks like a constructor. Behaves like a constructor (0 init).

int a(b);  // Again.

لذلك من الناحية الفنية لا يوجد منشئات لأنواع POD الأساسية. ولكن لجميع النوايا والأغراض يتصرفون تماما مثل لديهم منشئ نسخة ومنشئ افتراضي (عند تهيئة مع الأقواس).

إذا كان يبدو وكأنه بطة والدجالون مثل بطة ، ثم مثل بطة جدا.





c++ stl vector stdvector