Search code examples
c++inheritancepolymorphismmultiple-inheritance

How to convert a vector of parent pointers to another in c++?


How to convert two parent pointers in c++? This is the code.

// base class
class B {
    public:
       virtual ~B() {};
    // other code
};
class A {
    public:
       virtual ~A() {};
    // other code
};

// child class
class C1 : public A, B {
    public:
       virtual ~C1() {};    
    // other code
};
class C2 : public A, B {
    public:
       virtual ~C2() {};
    // other code
};
// ...other C class

There is a std::vector<std::shared_ptr<A>> which items point to instance C1 or C2 ...Cn.
Does anyone know how to convert the vector to a std::vector<std::shared_ptr<B>>?


Solution

  • Your code has typos. Missing public in inheritance of B when defining C<x> breaks stuff.

    After this is fixed sidecast does the job as it should:

    dynamic_cast conversion - cppreference.com

    b) Otherwise, if expression points/refers to a public base of the most derived object, and, simultaneously, the most derived object has an unambiguous public base class of type Derived, the result of the cast points/refers to that Derived (This is known as a "sidecast".)

    // base class
    class B {
    public:
        virtual ~B() { }
    };
    class A {
    public:
        virtual ~A() { }
    };
    
    class C1 : public A, public B {
    public:
        virtual ~C1() { }
    };
    
    class C2 : public A, public B {
    public:
        virtual ~C2() { }
    };
    
    
    TEST(SideCast, sigleItemCast)
    {
        C2 x;
        A* a = &x;
        auto b = dynamic_cast<B*>(a);
        ASSERT_THAT(b, testing::NotNull());
    }
    
    TEST(SideCast, sideCastOfVectorContent)
    {
        std::vector<std::shared_ptr<A>> v { std::make_shared<C1>(), std::make_shared<C2>() };
        std::vector<std::shared_ptr<B>> x;
        std::transform(v.begin(), v.end(), std::back_inserter(x), 
            [](auto p) { return std::dynamic_pointer_cast<B>(p); });
    
        ASSERT_THAT(x, testing::Each(testing::NotNull()));
    }
    

    Live demo