سؤال

دعونا نقول كنت ترغب في تخزين متجه من LPD3DXSPRITE الكائنات.خط لاعلان هذا الرمز سيكون std::vector<LPD3DXSPRITE> sprites; يجب أن تكون قادرة على خلق العفريت مع:

LPD3DXSPRITE sprite = NULL;
D3DXCreateSprite(myRenderingDevice, &sprite);

أخيرا ، يجب أن تكون قادرا على إضافة هذا إلى ناقلات مثل ذلك:

sprites.push_back(sprite);

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

تحرير:

هذا قد يكون مفيدا أيضا.مكدس الاستدعاءات ينتج عن هذه الوظيفة التي vector<ID3DXSprite *, std::allocator<ID3DXSprite *>>::push_back(ID3DXSprite * const &_Val=0x0036fd38 هو ما يسمى.ليس هذا هو المتجه الذي تم إقراره.
ومع ذلك ، LPD3DXSPRITE هو مجرد typedef على ID3DXSprite *.وهذا يمكن أن يحقق أي شيء إلى النور ؟

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

المحلول

بعد النظر من خلال الكود الخاص بك ، وجدت المشكلة.شيء أن ننظر عندما تحصل على أي فواصل في التطبيق الخاص بك هو "Autos" علامة التبويب أو السكان المحليين من علامة التبويب.هنا ستلاحظ شيئا عن this المؤشر:انها فارغة!

وهذا يعني على سبيل المثال أن AddSprite هو أن يطلق على غير موجودة.هذا هو الخاص بك SpriteManager, الذي أراه هو المفرد.في الرئيسي الخاص بك, لا يمكنك إنشاء مثيل من ذلك.

كان علي أن أفعل بعض الأشياء للحصول على عمل.أنا وشملت "LudoRenderer/SpriteManager.h" في Main.cpp, و أضاف CreateInstance الاتصال:

SpriteManager::CreateInstance();

المشكلة الوحيدة مع ذلك هو أن كنت قد أعلنت المنشئ الخاص بك/المدمر خاصة ، مثل غيرها من ووحدانية ، ولكن لم يعرف لهم, هكذا فعلت ذلك أيضا:

SpriteManager::SpriteManager(){}
SpriteManager::~SpriteManager(){} 

بعد هذه التغييرات ، فإنه "عمل".هذا في الاقتباس لأن يتم حل مشكلتك ، ولكن هناك خطأ آخر لاحقا في التعليمات البرمجية m_GameManager->SetWagon(m_Wagon);.

هنا ، m_GameManager لم يتم تهيئة.أنا uncommented m_GameManager = GameManager::GetInstance(); على خط 43 في LudoEngine.cpp, مما جعلنا في نفس المشكلة قبل لا CreateInstance يدعى.أضفت رأس اللازمة في الرئيسية ، ودعا إنشاء الطريقة.هذا إصلاح المشكلة ، و المحرك الخاص بك ران (العرض رائع أيضا!)

كان هناك حادث تحطم على الخروج ، ErrorLogger::LogError, لأن ErrorLogger كانت فارغة.كانت تسمى في LudoMemory's المدمر ، ولكن سأترك هذا واحد بالنسبة لك.:)

الآن اثنين من نصائح انا tihnk التي من شأنها أن تساعد.الأول هو حول هذه المسألة نحن حل.عادة, وحدانية خلق أنفسهم إذا لم تكن بالفعل.أود تغيير المفرد GetInstance أن شيئا من هذا القبيل:

static T *GetInstance ( )
{
    if (!m_Singleton) // or == NULL or whatever you prefer
    {
        CreateInstance();
    }

    return m_Singleton; // not sure what the cast was for
}

وهذه القوة إنشاء المفرد إذا كان لم يتم بالفعل.الآن, إذا كنت ترغب للمستخدمين الاتصال CreateInstance قبل محاولة GetInstance, أنت يمكن أن تضيف نوعا من التحذير:

static T *GetInstance ( )
{
    if (!m_Singleton) // or == NULL or whatever you prefer
    {
        CreateInstance();
        std::cerr << "Warning, late creation of singleton!" << std::endl;

        // or perhaps:
        ErrorLogger::GetInstance()->
                        LogError(L"Warning, late creation of singleton!");
    }

    return m_Singleton;
}

منذ أن يترك المعلومات الهامة "التي المفرد?", يمكنك دائما في محاولة لإضافة typeinfo إلى ذلك:

#include <typeinfo>

// ...

std::cerr << "Warning, late creation of singleton: "
          << typeid(T).name() << std::endl;

في محاولة للحصول على بعض نوع الأسماء هناك.

وأخيرا لا بأس أن delete 0, جهاز فحص حذف الماكرو ليست هناك حاجة.

إلى توضيح ما لديك LUDO_SAFE_DELETE, الذي يتحقق إذا لم تكن فارغة قبل أن يدعو حذف.في C++, حذف باطل ليس له أي تأثير ، لذلك الشيك ليست هناك حاجة.جميع حالات الخاص بك آمنة لحذف يمكن استبدال فقط مع الخاص بك LUDO_DELETE.

نصائح أخرى

رمز تبدو على ما يرام بالنسبة لي.ولكن كنت تخزين مؤشر إلى ID3DXSprite في ناقلات.كيف دي-يخصص ؟ هل من الممكن العفريت تم إلغاء تخصيص ناقلات ينتهي عقد مؤشر غير صالح ثم محاولات إشارة المؤشر ؟

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