لماذا لا يمكنني تعيين القيمة الصحيحة إلى متغير نوع التعداد C ++؟

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

سؤال

لا أستطيع أن أفهم ما الذي يحدث هناك. باستخدام Visual Studio 2008 ، لقد حددت تعدادًا مثل هذا:

enum MyType{
    A,
    B,
    C
};

ثم أستخدمه لتهيئة متغير عضو:

class MyClass
{
    private:
        bool   bit_;
        uint16 num_;
        MyType member_;
    public:
        MyClass(MyType value){
            member_ = value; // This the assignment which fails
        } // Here, there's a breakpoint to query member_ value    
};

مثيل myClass = جديد myClass () ؛

أنا أستخدم تكوين تصحيح التصحيح ، لذلك لا يمكن أن يخدعني أي تحسين عند قراءة متغير. عند نقطة توقف مباشرة بعد المهمة ، يعرض مصحح الأخطاء قيمة العضو as member_ = C.

يمكن أن تكون مشكلة في تحديث تصحيح الأخطاء ، ولكن داخل طريقة تقوم بتقييمها الصحيحة عند التحقق:

if(member_ == C){
    // ??
}

وأيضًا ، يعطي تعيين القيم الأخرى أرقامًا غريبة ، مثل القيام بذلك member_ = B يعطي member_ = 258 عند تقطيعه. هل يمكن أن تخبرني ما هو الخطأ؟ شكرا مقدما.

تحرير #1

لقد لاحظت تأثيرًا مضحكًا يفسر لماذا بعد التعيين member_ = A التعبير member_ == C يقيم true للحصول على التعداد مع القيم الافتراضية:

للعنونة

enum MyType{ A, B, C}; // equivalent to enum MyType{ A = 0, B = 1, C = 2};

انا حصلت

MyType  a = A; // but when fetching a the value is   2  (0x0002)  thats the map for C!
MyType  b = B; // but when fetching a the value is 258  (0x0102)
MyType  c = C; // but when fetching a the value is 514  (0x0202)

ولكن إذا صنعت

enum MyType{ A = 5, B = 6, C = 7};

انا حصلت

MyType  a = A; // but when fetching a the value is 1282  (0x0502)
MyType  b = B; // but when fetching a the value is 1538  (0x0602)
MyType  c = C; // but when fetching a the value is 1794  (0x0702)

لذلك ، عند تعيين هذا #؟!

راجع للشغل ، صنع نوع من member_ أن تكون int في حين أن MyType لا يتغير لا شيء.

تحرير #2أضاف عضوين آخرين إلى الفصل ، وهما السبب الحقيقي للمشكلة. سأقوم بنشر الإجابة بمجرد اختفاء القيود الزمنية (8 ساعات من نشر السؤال).

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

المحلول 2

شكرا لكم جميعا. أشارني شخص ما في العمل إلى أصل المشكلة.

إنها مسألة التكوين الخاطئ للمشروع ، والتي تعطي مشكلات محاذاة البيانات.

بعد التجميع ، مع إعدادات المشروع الحالية ، فإن أول عضوين من الفصل هما 3 بايت من الحجم.

يجب أن يكون 4 بايت ، وبالتالي اختلال بايت 1. الإضافي المضافة هو القمامة في البايت غير المحسوب ، لذلك ، فإن التأثير الكامل هو تغيير بايت واحد وإضافة 2.

تم إلغاء هذا التأثير إضافة عضو إضافي ، على الرغم من أنه ليس حلاً أنيقًا (الحل هو تكوين المشروع بشكل عام).

class MyClass
{
    private:
        bool   bit_;  // 1 byte
        uint16 num_;  // 2 byte

        bool dummy;   // extra byte to help the alignment

        MyType member_;
    public:
        MyClass(MyType value){
            member_ = value; // Now it works as expected.
        }
};

نصائح أخرى

إدخالات التعداد لا يجب أن يكون لها قيم فريدة. قد يكون لديك تعداد مع A و B و C حيث كل من A و C يساوي "42". في مثل هذه الحالة ، عندما يكون VAR قيمة 42 ، IDE سوف تظهر لك واحدة فقط من الإدخالات المطابقة ، A أو C ، وليس كلاهما.

يمكنك بسهولة إنشاء التعداد مع إدخالات "مكررة" ، مثل هذا:

enum { A=1, B=1, C=1 }

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

enum { A, B, C }       // 0,1,2
enum { A, B, C=0 }     // 0,1,0
enum { A=2, B=1, C }   // 2,1,2
enum { A=-1, B, C=0 }  // -1,0,0

تأكد من التحقق من تعريف التعداد الخاص بك.

انظر IE http://www.learncpp.com/cpp-tutorial/45-enumerated-types/

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