Как получить данные из списка std :: list, содержащего boost :: shared_ptr - PullRequest
0 голосов
/ 09 февраля 2012

Мне нужна помощь при попытке восстановить данные, хранящиеся в std::list<boost::shared_ptr<boost::any>>

Я работаю над классом Singleton Controller с личным std::list. Клиентские классы могут добавлять / удалять / редактировать конкретные объекты классов, которые будут использоваться программой через этот класс Controller.

Причина использования boost::shared_ptr заключается в том, что я назначаю уникальный objID каждому созданному конкретному классу. После добавления экземпляра objs в контроллер пользователь сможет искать и удалять объекты позже. Перегруженные методы Add(....) и Remove(...) для каждого конкретного класса работают нормально.

Я сейчас пытаюсь создать getObject(int index) & setObject(int index) методы, но не могу понять, как привести возвращенный указатель к классу Concrete.

Пожалуйста, сообщите.

Мой текущий код:

//===============================================================
//Singleton.h controller class
private:    
static Singleton *mgr;

typedef boost::shared_ptr<boost::any> Shapes_Ptr;
//private static list
static std::list<Shapes_Ptr> shapes; 

public:
const Shapes_Ptr getObject( int index) const;  //Return Shape
Shapes_Ptr EditObject( const int index );      //Edit Shape

Info();  //Prints contents of instance to console screen

//===============================================================
//Singleton.cpp 

//Return Shape
const Shapes_Ptr getObject( int index) const
{
    int cc = 0;

    if ( (int)shapes.size() > ZERO && index < (int)shapes.size() )
    {
        list<Shapes_Ptr>::const_iterator i;

        for ( i = shapes.begin(); i != shapes.end(); ++i )
        {
            if ( cc == index )
            {
                return (*i);
                break;
            } 
            else { ++cc; }
        }//for-loop 
    }   
}

//Edit Shape
Shapes_Ptr EditObject( const int index )
{
    //same code as getObject()...
}


//===============================================================
//main.cpp 

Singleton *contrl= Singleton::Instance();

int main()
{
    for ( int i=0; i< 2; ++i )
    {
        contrl->CreateObject(Box2D() );
    }

    for ( int i = contrl->Begin(); i< contrl->End(); ++i )
    {
        if ( boost::any_cast<boost::any> (contrl->getObject(i)).type() == typeid(Physics::Box2D) )
        {
            //Code compiles but crashes on launch....
            any_cast<Box2D> (contrl->getObject(i) ).Info(); // <== ERROR CODE
        }
        //More if checks for other Concrete classes....
    }
}

1 Ответ

0 голосов
/ 10 февраля 2012

Если оставить в стороне какую-то конкретную проблему с вашим текущим кодом, я думаю, что есть проблема с вашим дизайном.

У вас есть этот класс менеджера Singleton, который действует как своего рода пул, а также, как вы говорите, присваивает уникальные идентификаторы каждому объекту, чтобы их можно было найти позже. Но вы знаете, что позволяет коду находить объекты? Указатели! Если вы используете обычный пул, по одному для каждой иерархии типов (так что не используйте Boost Any), вы можете найти его таким же полезным, и он будет менее неприятным, если / else проверяет код проверки типа (что все согласны с тем, что это не очень хорошее применение RTTI, кроме плохой ООП).

Итак, что ты скажешь? Бросьте это, и используйте Boost Pool, если вы хотите что-то выделить ваши объекты из центрального места, и используйте указатели в качестве ваших уникальных идентификаторов, таким образом избегая поиска по пути.

...