سؤال

في C++ لدي الدرجة التي تحتوي على مجهول bitfield البنية.أريد أن تهيئة إلى الصفر دون الحاجة إلى يدويا كتابة كل المجالات.

لا يمكن تخيل وضع التهيئة في ثلاثة أماكن:

  1. إنشاء منشئ في bitfield
  2. صفر في مهيئ قائمة منشئ عن الطبقة التي تحتوي على
  3. صفر في الجسم من منشئ عن الطبقة التي تحتوي على

هذا bitfield العديد من المجالات ، وأنا أفضل أن لا قائمة لهم جميعا.

على سبيل المثال انظر التعليمات البرمجية التالية:

class Big {
    public:
        Big();

        // Bitfield struct
        struct bflag_struct {
            unsigned int field1 : 1;
            unsigned int field2 : 2;
            unsigned int field3 : 1;
            // ...
            unsigned int field20 : 1;
            // bflag_struct(); <--- Here?
        } bflag;

        unsigned int integer_member;
        Big         *pointer_member;
}

Big::Big()
  : bflag(),             // <--- Can I zero bflag here?
    integer_member(0),
    pointer_member(NULL)
{
    // Or here?
}

هو واحد من هذه الأفضل ؟ أو هل هناك شيء آخر أنا في عداد المفقودين ؟

تحرير:على أساس قبول الإجابة أدناه (من قبل فيروتشيو) أنا استقر على هذا الحل:

class Big {
    // ...

    struct bflag_struct {
        unsigned int field 1 : 1;
        // ...
        bflag_struct() { memset(this, 0, sizeof *this); };
    }

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

المحلول

يمكنك أن تفعل ذلك دائما في المنشئ الخاص بك:

memset(&bflag, 0, sizeof bflag);

نصائح أخرى

الاتحاد bitfield البنية مع شيء أسهل لتهيئة إلى 0.

هل يمكن استخدام الاتحاد, على الرغم من أن هذا من شأنه أن يضيف مستوى إضافي من المراوغة عند الوصول إلى الحقول:

class Big {
    union {
        struct {
            unsigned int field1 : 1;
            ...
        } fields;
        unsigned int all_fields;
    };
    ...
};

Big::Big()
  : all_fields(0),
    ...
{
    ...
}

MSVC يسمح مجهول البنيات داخل النقابات (انظر ، على سبيل المثالتعريف D3DMATRIX في <d3d9.h>) لكن هذا غير القياسية C++ التمديد التي يجب تجنب استخدام إذا كنت تستطيع.

بوصفها جانبا ، إلا إذا كنت في حاجة إلى bitfield إلى واجهة بعض التعليمات البرمجية القديمة, يجب أن لا تستخدم لهم.فهي بطبيعتها unportable وغير فعالة.

استخدام وظيفة مثل مهيئ (وضع علامة "يمكنني صفر bflag هنا؟") هو 100 ٪ كافية لتهيئة جراب الخاص بك البنية مع 0 القيم.

إلا إذا كنت تعرف أن المترجم هو كسر في هذا الصدد القيام بأي إضافية التهيئة من هؤلاء الأعضاء هو تهيئة مرتين دون فائدة.

تحرير:فقط 'متعة' راجعت فقط هذا مع VS2005, VS2008 دول مجلس التعاون الخليجي 3.4.4 دول مجلس التعاون الخليجي 4.2 و Borland C++ 5.5.1 ...فقط Borland C++ 5.5.1 يحصل على خطأ.

وأنا أقول 'خطأ' لأنه يبدو لي أن 8.5 و 8.5.1 القياسية يعني أن وظيفة مثل مهيئ يجب صفر-الحرف الأول جراب البنية.

يمكنك صفر الذاكرة باستخدام ZeroMemory أو memset في منشئ الطريقة التي تبدو الأنظف.

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