ماذا تعني العبارات التالية في لغة C++:تهيئة الصفر والافتراضي والقيمة؟

StackOverflow https://stackoverflow.com/questions/1613341

  •  06-07-2019
  •  | 
  •  

سؤال

ماذا تعني العبارات التالية في لغة C++:

  • التهيئة الصفرية,

  • التهيئة الافتراضية، و

  • تهيئة القيمة

ما الذي يجب أن يعرفه مطور C++ عنهم؟

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

المحلول

هناك شيء واحد يجب إدراكه وهو أن "تهيئة القيمة" أمر جديد في معيار C++ 2003 - فهو غير موجود في معيار 1998 الأصلي (أعتقد أنه قد يكون الاختلاف الوحيد الذي هو أكثر من مجرد توضيح).يرى كيريل ف.إجابة ليادفينسكي للتعاريف مباشرة من المعيار.

انظر هذه الإجابة السابقة حول سلوك operator new للحصول على تفاصيل حول السلوك المختلف لهذا النوع من التهيئة ومتى يبدأ (وعندما يختلف من c++ 98 إلى C++ 03):

النقطة الأساسية في الإجابة هي:

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

  • في C++ 1998 هناك نوعان من التهيئة:الصفر والافتراضي
  • في C++ 2003، تم إضافة نوع ثالث من التهيئة، وهو تهيئة القيمة.

أقل ما يمكن قوله هو أن الأمر معقد إلى حد ما، وعندما يتم تنفيذ الأساليب المختلفة تكون خفية.

شيء واحد يجب أن تكون على دراية به بالتأكيد هو أن MSVC يتبع قواعد C++ 98، حتى في VS 2008 (VC 9 أو cl.exe الإصدار 15.x).

يوضح المقتطف التالي أن MSVC وDigital Mars يتبعان قواعد C++98، في حين يتبعGC 3.4.5 وComeau قواعد C++03:

#include <stdio.h>
#include <string.h>
#include <new>

struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

int main()
{
    char buf[sizeof(B)];
    memset( buf, 0x5a, sizeof( buf));

    // use placement new on the memset'ed buffer to make sure 
    //  if we see a zero result it's due to an explicit 
    //  value initialization
    B* pB = new(buf) B();   //C++98 rules - pB->m is uninitialized
                            //C++03 rules - pB->m is set to 0
    printf( "m  is %d\n", pB->m);
    return 0;
}

نصائح أخرى

معيار C++03 8.5/5:

ل تهيئة صفرية كائن من النوع 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 هو نوع مصفوفة، فسيتم تهيئة كل عنصر بقيمة؛
- وبخلاف ذلك، تتم تهيئة الكائن صفرًا

البرنامج الذي يستدعي التهيئة الافتراضية أو تهيئة القيمة لكيان من النوع المرجعي هو برنامج غير صحيح.إذا كان T هو نوع مؤهل لسيرة ذاتية، فسيتم استخدام إصدار السيرة الذاتية غير المؤهل لـ T لهذه التعريفات الخاصة بالتهيئة الصفرية، والتهيئة الافتراضية، وتهيئة القيمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top