سؤال

لدي فئة أساسية وفئة مشتقة. كل فئة لديها ملف .h وملف .cpp.

أقوم به Dynamic_Cast لكائن الفئة الأساسية للفئة المشتقة في التعليمات البرمجية التالية:

H الملفات:

class Base
{
  public:
    Base();
    virtual ~Base();
};

class Derived : public Base
{
  public:
    Derived(){};
    void foo();
};

class Another
{
  public:
    Another(){};
    void bar(Base* pointerToBaseObject);
};

ملفات CPP:

Base::Base()
{
    //do something....
}
Base::~Base()
{
    //do something....
}
void Derived::foo()
{
    Another a;
    a.bar(this);
}
void Another::bar(Base* pointerToBaseObject)
{
    dynamic_cast<Derived*>(pointerToBaseObject)
}

من بعض السبب الغريب، فشل الصب (إرجاع NULL). ومع ذلك، تنجح الصب إذا قمت بنقل تنفيذ منشئ الفئة المشتقة من .h إلى ملف .cpp.

ماذا يمكن أن يسبب ذلك؟

المحول البرمجي هو GCC 3.1، على Linux-suse. راجع للشغل، أرى هذا السلوك فقط على هذه المنصة، ونفس الرمز يعمل بشكل جيد في Visual Studio.

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

المحلول

يجب أن لا يفشل الكود، كما هو منشور، بشرط أن يكون لديك وظيفة افتراضية في الفئة الأساسية (كما أشار LITB).

لكنني أعتقد أن كل مترجم الحالي يولد "فئة أساسية ليست متعددة الجنس" نوع الخطأ إذا لم يكن لديك، لذلك ربما لن تكون المشكلة.

الشيء الوحيد الذي يمكنني التفكير فيه هو أنه بسبب بعض الأخطاء الغريب، يتم إبزيم كل شيء ولا يتم إنشاؤه بدون vtable. ولكن إذا وضعت المنشئ في ملف C ++، فإن التحويل البرمجي يقرر عدم ضم كل شيء، مما يؤدي إلى إنشاء VTable، مما تسبب في عملك.

ولكن هذا هو التخمين البري للغاية، ولا أعتقد أن أي مترجم سيكون لديه خطأ في ذلك (؟)

إذا كنت تريد إجابة محددة، أضف المزيد من التعليمات البرمجية. والمبرم / النظام الأساسي المستخدمة.

تحرير: رؤية التعليمات البرمجية المحدثة

أعتقد أنك يجب أن تستمد على الأقل مستمدة من القاعدة؛) (أفترض أن هذا خطأ مطبعي)

ولكن بعد رؤية التعليمات البرمجية، الشيء الوحيد الذي يمكنني التفكير فيه هو أن دول مجلس التعاون الخليجي (خطأ) في كل شيء ولا تولد vtable للمشتق. لما يستحق، هذا يدير غرامة تجميعها مع دول مجلس التعاون الخليجي

3.1 أكثر من 7 سنوات من العمر الآن ... إذا كان هناك أي إمكانية للترقية سأذهب لذلك.

نصائح أخرى

هل لديك أي وظيفة افتراضية في قاعدة؟ لن تعمل بطريقة أخرى. إذا لم يكن هناك شيء آخر، فقم بإجراء الظاهري DTOR الظاهري.

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

اجعل المدمر الظاهري، ووضعه (أو طريقة افتراضية واحدة على الأقل) في ملف .cpp.

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

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

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

هل تفعل هذا في Visual C ++؟ أعتقد أنك تستخدم لتتمكن من تمكين معلومات نوع التشغيل (RTTI) في إعداد برنامج التحويل البرمجي لهذا العمل.

من فضلك لا تهمني إذا كان لدي هذا الخطأ. لقد مر بعض الوقت منذ أن استخدمت C ++ !!!

في النظر إلى التعليمات البرمجية الخاصة بك، لا أرى أي ميراث. هل نسيت أن تفعل ذلك؟ المستمدة غير مشتق من أي شيء.

في الكود الذي نشرته مشتقة غير مشتق من القاعدة.

يحرر: FYI، التعليمات البرمجية المعدلة تعمل بشكل جيد مع G ++ 3.4.5

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