سؤال

أنا متأكد تمامًا من أن صفائف الأنواع المضمنة يتم توحيدها، في حين تتم تهيئة صفائف UDT بشكل افتراضي.

int foo[5]; // will contain junk
Foo foo[5]; // will contain 5 Foo objects that are default initialized

يحدث هذا بغض النظر عما إذا كان الصفيف مخصصًا على المكدس أو الكومة.

ومع ذلك، أجد صعوبة في العثور على مصدر موثوق في هذا الشأن.يقول بيارن أن:

"تتم تهيئة أعضاء المصفوفات والهياكل بشكل افتراضي أو لا يعتمد ذلك على ما إذا كانت المصفوفة أو البنية ثابتة" وهو ما لا يخبرني كثيرًا حقًا.

لقد حاولت أيضًا العثور على شيء ما في المعيار، ولكن حتى الآن لا جدوى.

فهل يعرف أحد مصدرا موثوقا يؤكد ما ورد أعلاه؟

هل كانت مفيدة؟

المحلول

يعتبر ISO C++ 03 موثوقًا بقدر ما يحصل:

بنية POD هي فئة مجمعة لا تحتوي على أعضاء بيانات غير ثابتين من النوع غير POD-struct أو غير POD-union (أو صفيف من هذه الأنواع) أو مرجع، ولا تحتوي على مشغل تعيين نسخة محدد من قبل المستخدم ولا المدمرة المعرفة من قبل المستخدم.وبالمثل، فإن اتحاد POD هو اتحاد تجميعي لا يحتوي على أعضاء بيانات غير ثابتة من النوع غير POD-struct، أو غير POD-union (أو مصفوفة من هذه الأنواع) أو مرجع، ولا يحتوي على عامل تعيين نسخة محدد من قبل المستخدم ولا يوجد مدمر محدد من قبل المستخدم.فئة POD هي فئة تكون إما بنية POD أو اتحاد POD.

الأنواع الحسابية (3.9.1)، وأنواع التعداد، وأنواع المؤشر، ومؤشر لأنواع الأعضاء (3.9.2)، والإصدارات المؤهلة السيرة الذاتية من هذه الأنواع (3.9.3) تسمى بشكل جماعي الأنواع العددية.الأنواع العددية، وأنواع بنية POD، وأنواع اتحاد POD (البند 9)، والمصفوفات من هذه الأنواع والإصدارات المؤهلة السيرة الذاتية لهذه الأنواع (3.9.3) تسمى مجتمعة أنواع POD.

تعني التهيئة الصفرية لكائن من النوع T ما يلي:

  • إذا كان T من النوع العددي (3.9)، فسيتم تعيين الكائن على قيمة 0 (صفر) محولاً إلى T؛
  • إذا كان T هو نوع فئة غير نقابة ، فإن كل عضو في البيانات غير مستقلة وكل مشروع فرعي من الفئة الأساسية هو صفر ؛
  • إذا كان T هو نوع اتحاد، فإن أول عضو بيانات مسمى للكائن هو صفر؛
  • إذا كان T عبارة عن نوع مصفوفة، فستتم تهيئة كل عنصر بصفر؛
  • إذا كان T هو نوع مرجعي، فلن يتم إجراء أي تهيئة.

تعني التهيئة الافتراضية لكائن من النوع T ما يلي:

  • إذا كان T هو نوع فئة غير POD (البند 9)، فسيتم استدعاء المُنشئ الافتراضي لـ T (وتكون التهيئة سيئة التكوين إذا لم يكن لدى T مُنشئ افتراضي يمكن الوصول إليه)؛
  • إذا كان T هو نوع مصفوفة، فستتم تهيئة كل عنصر افتراضيًا؛
  • وبخلاف ذلك، تتم تهيئة الكائن بصفر.

تعني تهيئة قيمة كائن من النوع T ما يلي:

  • إذا كان T هو نوع فئة (البند 9) مع مُنشئ مُعلن من قبل المستخدم (12.1)، فسيتم استدعاء المُنشئ الافتراضي لـ T (والتهيئة تكون سيئة التشكيل إذا لم يكن لدى T مُنشئ افتراضي يمكن الوصول إليه)؛
  • إذا كان T هو نوع فئة غير اتحادية بدون مُنشئ معلن من قبل المستخدم، فسيتم تهيئة كل عضو بيانات غير ثابت ومكون فئة أساسية لـ T؛
  • إذا كان T هو نوع مصفوفة، فسيتم تهيئة كل عنصر بقيمة؛
  • وبخلاف ذلك، تتم تهيئة الكائن بصفر

يجب أن تتم تهيئة كل كائن لمدة تخزين ثابتة صفرًا عند بدء تشغيل البرنامج قبل إجراء أي تهيئة أخرى.[ملحوظة:في بعض الحالات، تتم التهيئة الإضافية لاحقًا.]

يجب أن تتم تهيئة الكائن الذي يكون مُهيئه عبارة عن مجموعة فارغة من الأقواس، على سبيل المثال، ()، بقيمة تهيئة.

إذا لم يتم تحديد مُهيئ لكائن ما، وكان الكائن من نوع فئة غير POD (من المحتمل أن يكون مؤهلًا للسيرة الذاتية) (أو صفيفًا منه)، فيجب أن تتم تهيئة الكائن افتراضيًا؛إذا كان الكائن من النوع المؤهل const، فيجب أن يكون لنوع الفئة الأساسي مُنشئ افتراضي معلن من قبل المستخدم.بخلاف ذلك، إذا لم يتم تحديد مُهيئ لكائن غير ثابت، فإن الكائن وكائناته الفرعية، إن وجدت، يكون لها قيمة أولية غير محددة)؛إذا كان الكائن أو أي من كائناته الفرعية من النوع المؤهل الثابت، يكون البرنامج سيئ التكوين.

على سبيل المثال الخاص بك، int هو بالتأكيد نوع POD (إنه نوع حسابي)، وبالتالي فهو نوع محلي أو حقل من النوع int, ، في غياب المُهيئ، سيكون له قيمة غير محددة.ل Foo, ، هذا يعتمد على كيفية تعريفه - تقريبًا، إذا لم يكن لديه مُنشئ، وجميع أعضائه من أنواع POD، فهو في حد ذاته نوع POD، ولا تتم أي تهيئة أيضًا.خلاف ذلك، يتم استدعاء المنشئ الافتراضي.وحتى ذلك الحين، هذا لا يعني ذلك أعضاء تمت تهيئتها - القواعد متكررة، لذلك لن تتم تهيئة أعضاء POD من النوع غير POD إلا إذا قام المُنشئ من هذا النوع بذلك على وجه التحديد (في قائمة المُهيئات الخاصة به).

سيتم في جميع الحالات تهيئة المتغيرات والحقول الثابتة.لاحظ أن هذا ينطبق أيضًا على غير PODs - مما يعني أن المتغير الثابت لنوع الفئة مضمون لتعيين كافة الحقول بشكل متكرر على (T)0 حتى قبل تشغيل منشئه.

هناك خدعة مفيدة للتهيئة الافتراضية لأي نوع POD مجمع {} في المُهيئ - لاحظ أنه يعمل مع البنيات وكذلك المصفوفات:

char s[10] = {}; // all elements default-initialized
Foo foo = {};    // all fields recursively default-initialized

نصائح أخرى

وجاء في المعيار C ++، في 8.5.9:

<اقتباس فقرة>   

إذا لم يتم تحديد مهيئ ل   الاعتراض، والهدف من ذلك هو من (ربما   السيرة الذاتية-المؤهلة) غير POD من نوع الطبقة (أو   مجموعة منها)، يجب أن يكون الهدف   ، تهيئة الافتراضية. إذا كان الكائن   من نوع CONST المؤهلين، و   يجب الكامن وراء نوع فئة لديها   التي أعلنت المستخدم منشئ افتراضي.   خلاف ذلك، إذا لم يكن مهيئ هو   المحدد للكائن غير ثابت، و   الكائن ولا subobjects، إن وجدت،   لها قيمة الأولية غير محددة.

"يتم تهيئة أعضاء المصفوفات والهياكل بشكل افتراضي أو لا يعتمد ذلك على ما إذا كان المصفوفة أو البنية ثابتة"

وهذا أمر موثوق به، على الرغم من أنه يمكن أن يكون أكثر وضوحا:

  • تم الإعلان عن المصفوفات والهياكل كـ static تتم التهيئة إلى الأصفار.
  • المصفوفات والهياكل المحلية للأنواع المضمنة (أي. لا تتم تهيئة الأنواع التي ليس لها مُنشئات).
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top