размер контейнера в map имеет размер 1. [c++]

Есть статические класс. в нем много контейнеров map. Я например создаю кнопку и помещаю её в сцену с слоем 1. то есть в 0 слое у меня спрайты. а в 1 слое кнопки. я добавляю вот так. Scene<Button>::load ( btn, 1 );. и в этом слое появляются эти кнопки. но есть проблема. я например не хочу задумывать на каком слое есть виджеты и пишу в рендере так.

Scene<Button>::draw0 ( );
Scene<Actor>::draw0 ( );
Scene<Box>::draw0 ( );
Scene<Button>::draw1 ( );
Scene<Actor>::draw1 ( );
Scene<Box>::draw1 ( );

но игра segfault. я проверяю и оказывается что bmap0, bmap0 это map кнопки в слое 0, имеет размер 1 и пытается нарисовать объект. но я в этот слой кнопку не помещал. помещал только Actor. Блин, если я покажу код, то вы не захочите смотреть его наверное. ну ладно, покажу.

#ifndef __SCENE_H__
#define __SCENE_H__
#include <map>
#include <string>
#include <stdlib.h>
#include "actor.h"
#include "sprite.h"
#include "button.h"
#include "progress.h"
#include "font.h"

template <typename T>
class Scene {
    public:
        static inline std::map <std::string, Sprite *> map0;
        static inline std::map <std::string, Sprite *> map1;
        static inline std::map <std::string, Sprite *> map2;

        static inline std::map <std::string, Button *> bmap0;
        static inline std::map <std::string, Button *> bmap1;
        static inline std::map <std::string, Button *> bmap2;

        static inline std::map <std::string, Actor *> amap0;
        static inline std::map <std::string, Actor *> amap1;
        static inline std::map <std::string, Actor *> amap2;

        static inline std::map <std::string, Box *> bbmap0;
        static inline std::map <std::string, Box *> bbmap1;
        static inline std::map <std::string, Box *> bbmap2;


        static void clear ( Sprite *ssp ) {
            map0.clear ( );
            map1.clear ( );
            map2.clear ( );
        }
        static void clear ( Button *ssp ) {
            bmap0.clear ( );
            bmap1.clear ( );
            bmap2.clear ( );
        }
        static void clear ( Actor *ssp ) {
            amap0.clear ( );
            amap1.clear ( );
            amap2.clear ( );
        }
        static void clear ( Box *ssp ) {
            bbmap0.clear ( );
            bbmap1.clear ( );
            bbmap2.clear ( );
        }
        static void init ( ) {
            T *clean;
            clear ( clean );
        }

        static void get_view0 ( Box **view ) {
            bbmap0 [ (*view)->name ] = *view;
        }
        static void get_view1 ( Box **view ) {
            bbmap1 [ (*view)->name ] = *view;
        }
        static void get_view2 ( Box **view ) {
            bbmap2 [ (*view)->name ] = *view;
        }
        static void get_view0 ( Actor **view ) {
            amap0 [ (*view)->name ] = *view;
        }
        static void get_view1 ( Actor **view ) {
            amap1 [ (*view)->name ] = *view;
        }
        static void get_view2 ( Actor **view ) {
            amap2 [ (*view)->name ] = *view;
        }
        static void get_view0 ( Button **view ) {
            bmap0 [ (*view)->name ] = *view;
        }
        static void get_view1 ( Button **view ) {
            bmap1 [ (*view)->name ] = *view;
        }
        static void get_view2 ( Button **view ) {
            bmap2 [ (*view)->name ] = *view;
        }
        static void get_view0 ( Sprite **view ) {
            map0 [ (*view)->name ] = *view;
        }
        static void get_view1 ( Sprite **view ) {
            map1 [ (*view)->name ] = *view;
        }
        static void get_view2 ( Sprite **view ) {
            map2 [ (*view)->name ] = *view;
        }

        static void load ( T *obj, const int layer ) {
            switch ( layer ) {
                case 0: get_view0 ( &obj ); break;
                case 1: get_view1 ( &obj ); break;
                case 2: get_view2 ( &obj ); break;
                default: break;
            }
        }

        static void find_obj ( Box **view, const std::string str ) {
            *view = bbmap0 [ str ];
            if ( *view ) return;
            *view = bbmap1 [ str ];
            if ( *view ) return;
            *view = bbmap2 [ str ];
            if ( *view ) return;

        }
        static void find_obj ( Actor **view, const std::string str ) {
            *view = amap0 [ str ];
            if ( *view ) return;
            *view = amap1 [ str ];
            if ( *view ) return;
            *view = amap2 [ str ];
            if ( *view ) return;

        }
        static void find_obj ( Sprite **view, const std::string str ) {
            *view = map0 [ str ];
            if ( *view ) return;
            *view = map1 [ str ];
            if ( *view ) return;
            *view = map2 [ str ];
            if ( *view ) return;

        }
        static void find_obj ( Button **view, const std::string str ) {
            *view = bmap0 [ str ];
            if ( *view ) return;
            *view = bmap1 [ str ];
            if ( *view ) return;
            *view = bmap2 [ str ];
            if ( *view ) return;

        }

        static T *get_obj ( const char *str ) {
            T *obj;
            std::string s = str;
            find_obj ( &obj, s );
            return obj;
        }

        static void drawing_f0 ( Sprite *ssp ) {
            std::map<std::string, Sprite *>::iterator it = map0.begin();
            while ( it != map0.end() ) {
                it->second->draw ( );
                it++;
            }
        }
        static void drawing_f0 ( Button *ssp ) {
            std::map<std::string, Button *>::iterator bit = bmap0.begin();
            while ( bit != bmap0.end() ) {
                bit->second->draw ( );
                bit++;
            }
        }
        static void drawing_f0 ( Actor *ssp ) {
            std::map<std::string, Actor *>::iterator ait = amap0.begin();
            while ( ait != amap0.end() ) {
                if ( !ait->second->is_single ) ait->second->draw_single ( );
                else ait->second->draw ( );
                ait++;
            }
        }
        static void drawing_f0 ( Box *ssp ) {
            std::map<std::string, Box *>::iterator bbit = bbmap0.begin();
            while ( bbit != bbmap0.end() ) {
                bbit->second->draw ( );
                bbit++;
            }
        }

        static void draw0 ( ) {
            T *drawing;
            drawing_f0 ( drawing );
        }
        static void draw1 ( ) {
            std::map<std::string, Sprite *>::iterator it = map1.begin();
            while ( it != map1.end() ) {
                it->second->draw ( );
                it++;
            }
            std::map<std::string, Button *>::iterator bit = bmap1.begin();
            while ( bit != bmap1.end() ) {
                bit->second->draw ( );
                bit++;
            }
            std::map<std::string, Actor *>::iterator ait = amap1.begin();
            while ( ait != amap1.end() ) {
                if ( !ait->second->is_single ) ait->second->draw_single ( );
                else ait->second->draw ( );
                ait++;
            }
            std::map<std::string, Box *>::iterator bbit = bbmap1.begin();
            while ( bbit != bbmap1.end() ) {
                bbit->second->draw ( );
                bbit++;
            }
        }
        static void draw2 ( ) {
            std::map<std::string, Sprite *>::iterator it = map2.begin();
            while ( it != map2.end() ) {
                it->second->draw ( );
                it++;
            }
            std::map<std::string, Button *>::iterator bit = bmap2.begin();
            while ( bit != bmap2.end() ) {
                bit->second->draw ( );
                bit++;
            }
            std::map<std::string, Actor *>::iterator ait = amap2.begin();
            while ( ait != amap2.end() ) {
                if ( !ait->second->is_single ) ait->second->draw_single ( );
                else ait->second->draw ( );
                ait++;
            }
            std::map<std::string, Box *>::iterator bbit = bbmap2.begin();
            while ( bbit != bbmap2.end() ) {
                bbit->second->draw ( );
                bbit++;
            }
        }

        struct sbutton {
            Button *btn;
            std::string signal;
            void *data;
            void (*func) ( Button *btn, void *data );
        };

        static inline int count;
        static inline int index;
        static inline int start = 0;

        typedef struct sbutton *sbutton_ptr;
        static inline sbutton_ptr *sb;

        static void get_signal ( Button *btn, std::string &signal, void (*func) ( Button *btn, void *data ), void *data ) {
            count++;
            sb = ( sbutton_ptr * ) realloc ( sb, sizeof ( sbutton_ptr ) * count );
            sb[index] = ( struct sbutton * ) calloc ( 1, sizeof ( struct sbutton ) );
            sb[index]->btn = btn;
            sb[index]->signal = signal;
            sb[index]->data = data;
            sb[index]->func = func;
            index++;
        }

        static void signal ( T *widget, std::string signal, void (*func) ( Button *btn, void *data ), void *data ) {
            if ( start == 0 ) {
                sb = ( sbutton_ptr * ) calloc ( 0, sizeof ( sbutton_ptr ) );
                start = 1;
                count = 0;
                index = 0;
            }

            get_signal ( widget, signal, func, data );

        }

        static void event_signal_click ( int x, int y ) {
            int ss = 0;
            for ( int i = 0; i < count; i++ ) {
                Button *btn = sb[i]->btn;
                if ( x >= btn->box->x && x <= btn->box->box_width + btn->box->x ) {
                    if ( y >= btn->box->y && y <= btn->box->box_height + btn->box->y ) {
                        if ( sb[i]->signal == "click" ) {
                            btn->toggled = true;
                            sb[i]->func( btn, sb[i]->data );
                            ss = 1;
                        }
                    }
                }
                if ( ss == 0 ) {
                    btn->toggled = false;
                }
                ss = 1;
            }
        }

        static void event_signal_over ( int x, int y ) {
            int ss = 0;
            for ( int i = 0; i < count; i++ ) {
                Button *btn = sb[i]->btn;
                if ( x >= btn->box->x && x <= btn->box->box_width + btn->box->x ) {
                    if ( y >= btn->box->y && y <= btn->box->box_height + btn->box->y ) {
                        if ( sb[i]->signal == "over" ) {
                            btn->over = true;
                            sb[i]->func( btn, sb[i]->data );
                            return;
                        }
                    }
                }
                if ( ss == 0 ) {
                    btn->is_second = false;
                }
                ss = 1;
            }
        }
    private:
};
#endif

Ответы (1 шт):

Автор решения: KoVadim

Когда Вы пишите *view = bbmap0 [ str ]; то Вы либо получаете существующий объект (если он есть) либо (барабанная дробь) если элемента нет - он будет создан, для него будет вызван дефолтный конструктор!!! И естественно в этом случае у Вас будет мапа с одним элементом и Ваш указатель будет нулевым.

Что делать? Самый простой вариант - воспользоваться count.

if (bbmap0.count(str) == 0) {
  return;
}
*view = bbmap0 [ str ];

Второй способ - использовать find и итераторы.

→ Ссылка