Приведение производного classptrVector из baseclassptrVec, лучший способ? - PullRequest
0 голосов
/ 29 декабря 2010

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

Один из способов будет

создать новый производныйvector class с базовым классом ptr vector size

Зацикливание входящего вектора

Динамическое приведение базового указателя и заполнение производного вектора.

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

Ответы [ 3 ]

2 голосов
/ 29 декабря 2010

Если я правильно понял вопрос, у вас возникает следующая ситуация

class Base {};
class Derived: public Base {};
class Derived2: public Base {};

void foo(const vector<Derived*>&);

void bar()
{
  vector<Base*> baseVec;

  // Fill baseVec with pointers to Derived objects

  foo(baseVec); // Does not work
}

Проблема в том, что, хотя Base и Derived связаны через наследование, типы vector<Base*> и vector<Derived*> абсолютно не связаны.Между ними нет преобразования.
Кроме того, существует дополнительная проблема, заключающаяся в том, что baseVec может также содержать указатели на других производных классов, таких как Derived2, а foo не можетобработайте их.

Единственными реальными решениями являются

  • , изложенные в вопросе: создайте новый vector<Derived*> и заполните его dynamic_cast ed содержимым исходного вектора
  • избегайте такого несоответствия типов в программе.
1 голос
/ 29 декабря 2010

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

struct A {
  virtual ~A() {}
};

struct B : A {};

template< class Derived, class Base >
vector< Derived > const* dynamic_cast_vector( vector< Base > const& x )
{
  for ( typename vector< Base >::const_iterator i = x.begin(), e = x.end();
        i != e;
        ++ i ) {
    if ( ! dynamic_cast< Derived >( *i ) ) return 0;
  }

  return (vector< Derived > const*) &x;
}

int main()
{
  vector< A* >  av( 1, new A ), bv( 1, new B );
  dynamic_cast_vector< B* >( av ); // null
  dynamic_cast_vector< B* >( bv ); // ok
}

Надеюсь, это поможет

0 голосов
/ 16 февраля 2018

Если вы уверены, что в вашем baseclassptrVector есть только derivedclass указатели, вы можете обойти проверку типа C ++ с помощью:

derivedclassptrVector = reinterpret_cast<std::vector<derivedclass *> &>(baseclassptrVector);
...