मुझे सीआरटीपी टेम्पलेट में सदस्य सूचक के साथ कुछ परेशानी है। यहां कोड यह एक वर्चुअल कॉल फ़ंक्शन है जो एक crtp व्युत्पन्न वर्ग पर सदस्य फ़ंक्शन पॉइंटर को कॉल करता है।

class KeyboardHandler {
public:
    virtual void keyPressed(KeyboardKey) = 0;
    virtual void keyReleased(KeyboardKey) = 0;
    KeyboardHandler & operator=(const KeyboardHandler &) = default ;
};

template<class T>
class KeyboardHandlerOpti : public KeyboardHandler {
public:

    using KeyboardCallback = void (T::*)(KeyboardKey key, KeyboardStatus status) ;

KeyboardHandlerOpti(KeyboardCallback defaultCallback);

virtual void keyPressed(KeyboardKey key) override final;
virtual void keyReleased(KeyboardKey key) override final ;


std::vector<KeyboardCallback> mCallbackPressed ;
std::vector<KeyboardCallback> mCallbackReleased ;

KeyboardHandlerOpti & operator=(const KeyboardHandlerOpti &) = default ;

private:
    KeyboardCallback mDefaultCallback ;
};


class GlfwDefaultKeyboardHandler :
        public KeyboardHandlerOpti<GlfwDefaultKeyboardHandler> {
public:
    GlfwDefaultKeyboardHandler() ;

    GlfwDefaultKeyboardHandler & operator=(const GlfwDefaultKeyboardHandler &) = default ;

private:
    //This is type of KeyboardCallback
    void drawKey(KeyboardKey key, KeyboardStatus status) ;
} ;

क्लास GlfwDefaultKeyboardHandler को DrawKey के साथ KeyboardHandlerOpti::mDefaultCallback के रूप में प्रारंभ किया गया है

template<class T>
KeyboardHandlerOpti<T>::KeyboardHandlerOpti(KeyboardCallback    defaultCallback) :
    mDefaultCallback(defaultCallback),
    mCallbackPressed(getKeyboardKeyCount(), mDefaultCallback),
    mCallbackReleased(getKeyboardKeyCount(), mDefaultCallback) {
}

और कॉलबैक के साथ कहा जाता है

template<class T>
void KeyboardHandlerOpti<T>::keyPressed(KeyboardKey key) {
    KeyboardCallback c = mCallbackPressed[getKeyValue(key)] ;
    (dynamic_cast<T *>(this)->*c)(key, KeyboardStatus::ePressed) ;
    //(this->*c)(key, KeyboardStatus::ePressed) ;
}

दुर्भाग्य से मेरे पास एक सेगफॉल्ट है और मैं समझ नहीं पा रहा हूं कि क्यों। मुझे डिबग में कुछ दिलचस्प मूल्य मिला। मैं KeyboardHandlerOpti के निर्माण में देख सकता हूं कि मेरे पास ऐसी चीजें हैं जिन्हें मैं वास्तव में समझ नहीं पा रहा हूं।

डिफ़ॉल्ट कॉलबैक मान 0x4b7578 है और डीबगर फ़ंक्शन का नाम बता सकता है लेकिन mDefaultCallback "0x7ef360, यह समायोजन 96" है और यह दोनों वैक्टरों में समान मान है।

तो अगर कोई मुझे समझा सकता है कि मेरे पास सेगफॉल्ट क्यों है तो मुझे बहुत खुशी होगी।

0
Quentin Huot-Marchand 27 जून 2016, 18:59

1 उत्तर

सबसे बढ़िया उत्तर

सदस्यों को उस क्रम में प्रारंभ किया जाता है जिस क्रम में वे वर्ग परिभाषा में सूचीबद्ध होते हैं, नहीं क्रम में वे कंस्ट्रक्टर में प्रारंभकर्ता सूची में दिखाई देते हैं। KeyboardHandlerOpti कंस्ट्रक्टर में, mCallbackPressed और mCallbackReleased को पहले इनिशियलाइज़ किया जाता है, और उसके बाद ही mDefaultCallback को एक मान दिया जाता है। तो आप अपने वैक्टर को यादृच्छिक कचरे से भर देते हैं। औपचारिक रूप से, आपका प्रोग्राम अपरिभाषित व्यवहार प्रदर्शित करता है।

इसे बनाओ

template<class T>
KeyboardHandlerOpti<T>::KeyboardHandlerOpti(KeyboardCallback    defaultCallback) :
    mCallbackPressed(getKeyboardKeyCount(), defaultCallback),
    mCallbackReleased(getKeyboardKeyCount(), defaultCallback),
    mDefaultCallback(defaultCallback)
{
}

अर्थात्, सदिशों को आबाद करने के लिए defaultCallback का प्रयोग करें। mDefaultCallback को अंत तक ले जाना तकनीकी रूप से आवश्यक नहीं है, यह केवल सूची में क्रम को उस क्रम से मेल खाता है जिसमें प्रारंभकर्ता वास्तव में निष्पादित होते हैं (मेरा मानना ​​​​है कि कुछ कंपाइलर चेतावनी देते हैं जब प्रारंभकर्ता "गलत" क्रम में होते हैं)।

4
Igor Tandetnik 27 जून 2016, 19:55
वास्तव में बहुत बहुत धन्यवाद, मैंने चेतावनी नहीं देखी क्योंकि जीएलएम इतनी चेतावनियां उत्पन्न करता है क्योंकि मैं -पेडेंटिक का उपयोग करता हूं ....
 – 
Quentin Huot-Marchand
28 जून 2016, 00:41