Search code examples
c++vectorcastingmultiple-inheritancestdvector

C++ V-shape casting: vector<Base1*> to vector<Base2*>


I'm having real trouble to figure out this casting problem. Starting with 3 classes:

#include <vector>
// Pure virtual class
class Base1{
  public:
   virtual ~Base1();
   virtual void do_sth()=0;
}
class Base2{
  public:
   int prop=3;
   ~Base2();
}
class Derived: public Base1, Base2{
  ~Derived();
  void do_sth(){print("Hi");};
}

How can I perform the following conversion?

std::vector<Base1*> vec1
vec1.reserve(10);
for( int i = 0; i < 10; ++i )
    vec1.push_back(new Derived());

// To this type...?
std::vector<Base2*> vec2 = ?????;

Some remarks:

  • I'd use dynamic_cast to perform safe casting from Base1 to Derived.
  • Ideally, no object copies are made in the process!.
  • My best bet so far is to call vec2.data() to obtain a Base1* pointer, then dynamic_cast to Derived, then static cast to Base2, but I don't know how to transfer memory ownership nor how to pass vector size.

Solution

  • The comments to the question have gotten rather muddled, so I'll post this partial answer here, rather than trying to straighten out the comments.

    Base1 has a virtual function. Good start.

    Derived is derived from Base1.

    Derived is also derived from Base2.

    If you have an object of type Derived you can create a pointer to Base1 that points at the derived object:

    Derived d;
    Base1* b1 = &d;
    

    Now that you have a pointer to a polymorphic base class, you can use dynamic_cast to perform a cross-cast:

    Base2* b2 = dynamic_cast<Base2*>(b1);
    

    The compiler knows how to do that, and the result should be the same pointer value as you'd have gotten if you did it directly:

    Base2* b2x = &d;
    assert(b2x == b2);
    

    Note, too, that since the code traffics in vectors of pointers, it seems that the Derived objects are being created with new Derived. If that's the case, and eventually the code deletes the Derived object through a pointer to one of the base types, then the base type must have a virtual destructor.