Я сталкиваюсь с ситуацией, в которой у меня есть std::vector
из boost::shared_ptr
базового класса.В течение моей программы мне нужно хранить общие указатели для объектов производных классов и в этом векторе, а через некоторое время в программе нужно извлечь эти общие указатели.
Следующий код иллюстрирует мою проблему:
#include <iostream>
#include <vector>
using namespace std;
#include <boost/make_shared.hpp>
#include <boost/foreach.hpp>
class Base
{
public:
virtual ~Base()
{
}
};
/******************************************/
typedef boost::shared_ptr< Base > BasePtr;
/******************************************/
class Derived1 : public Base
{
public:
void derived1_test()
{
cout << "derived1_test" << endl;
}
/******************************************/
int i1;
};
/******************************************/
typedef boost::shared_ptr< Derived1 > Derived1Ptr;
/******************************************/
class Derived2 : public Base
{
public:
void derived2_test()
{
cout << "derived2_test" << endl;
}
/******************************************/
int i2;
};
/******************************************/
typedef boost::shared_ptr< Derived2 > Derived2Ptr;
/******************************************/
int main()
{
Derived1Ptr d1 = boost::make_shared< Derived1 >();
Derived2Ptr d2 = boost::make_shared< Derived2 >();
vector< BasePtr > v;
v.push_back( d1 );
v.push_back( d2 );
BOOST_FOREACH(BasePtr bPtr, v)
{
try
{
Derived1& d11 = dynamic_cast< Derived1& >( *bPtr );
d11.derived1_test();
}
catch (const std::bad_cast& e)
{
Derived2& d22 = dynamic_cast< Derived2& >( *bPtr );
d22.derived2_test();
}
}
return 0;
}
В приведенном выше коде, если я изменю код в BOOST_FOREACH
с
Derived1& d11 = dynamic_cast< Derived1& >( *bPtr );
на
Derived1Ptr d11 = dynamic_cast< Derived1Ptr >( bPtr );
, я получаю следующую ошибку времени компиляции на VS2010
invalid target type for dynamic_cast target type must be a pointer or reference to a defined class
Моя проблема в том, что я хочу работать с boost::shared_ptr
, а не ссылками.Во-вторых, я использую dynamic_cast
, который вызывает исключение std::bad_cast
, когда ссылка на объект другого типа (пробовал использовать его с общими указателями, но получал ошибку компилятора, упомянутую ранее).Это явно очень медленно.Я хочу использовать более ориентированный на производительность подход.То, что я ищу здесь, это любое решение вместо использования dynamic_cast
и обработки исключений.
Любые предложения относительно кода или изменения дизайна приветствуются.