динамическая ссылка на базовый класс в контейнере stl - PullRequest
0 голосов
/ 04 августа 2011

Можно ли хранить группу объектов по их базовому классу, скажем, в std :: list без указателей. Мне бы очень хотелось, чтобы объекты содержались в контейнере, а затем получить указатель на объект в контейнере и dynamic_cast, чтобы исправить производный класс.

У меня все отлично работает с помощью указателей. Нравится (супер простая версия):

class IComponent  
{   
    virtual ~Icomponent(){}  
}  

class PositionComponent: public IComponent  
{  
    //...  
    float x, y;  
}

std::list<IComponent*> CList;

//...  
// fill the list  
// put reference to object in pComponent
//...   

PositionComponent* position = dynamic_cast<PositionComponent*>( pComponent) 

position->x = 346452.235612;

Но управление памятью - огромная боль. Моя фактическая структура -

map<enumValue, map<int, IComponent*> >

У меня такое чувство, что я не могу использовать сами объекты, потому что, когда я добавляю какой-либо производный компонент в список, дополнительные данные будут обрезаны, и у меня останется только базовый класс. Это не фигурировало, пока я не попробовал static_cast вместо этого, и он потерпел крах.

Может ответить на мой первоначальный вопрос и / или подтвердить мои чувства по этому вопросу. Спасибо!

Ответы [ 3 ]

3 голосов
/ 04 августа 2011

, чтобы минимизировать боль при ручном управлении памятью, используйте умные указатели: std::unique_ptr, если ваш компилятор уже поддерживает это или boost::shared_ptr, но не std::auto_ptr, который не должен использоваться в контейнерах

2 голосов
/ 04 августа 2011

Как вы уже догадались, когда вы сохраняете объект в контейнере по значению, он разрезается и данные отсекаются.

Если вам нужно сохранить только один тип данных (вы показываете только один в вашемкод), тогда вы можете заставить контейнер содержать этот тип.

Если нет, вы действительно застряли с помощью указателей.Вы можете значительно упростить управление памятью, используя умный указатель или, если это уместно, какой-нибудь бустер ptr _контейнер.

Далее вам может понадобиться подумать, если вам нужно провести еще одну итерацию, учитывая вашидизайн, обеспечивающий интерфейс, который не требует выполнения dynamic_cast для восстановления исходного типа.

0 голосов
/ 04 августа 2011

Можно ли хранить группу объектов по их базовому классу, скажем, std :: list без указателей.

Это предложение кажется противоречивым в C ++ с точки зрения IMO. Поскольку контейнер STL может содержать только один и тот же тип объекта, если вы поместите производный объект в контейнер базового типа, он будет разрезан.

Таким образом, очевидное нормальное решение - использовать контейнер для хранения указателей базового типа, как вы (вы можете использовать boost / std интеллектуальный указатель для управления памятью)

Если вы действительно хотите хранить разные объекты в одном контейнере STL, вы можете рассмотреть возможность использования boost :: any .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...