Multiple inheritance going from one Base Class to another

121 Views Asked by At

Assunme I have some abstract class A. I want to cast into some other class B only if the dynamic type of A is a class that also inherits from B. Is there a good way to do this that doesn't involve checking all possible intermediate classes (since in my actual scenario, there is a ton of those)?

In other words, is there some process that will make the following code work?

#include <memory>
#include <cassert>

struct A
{
    virtual void foo() = 0;
};

struct B
{
    virtual void bar() = 0;
};

struct C : public A, public B
{
    void foo() override {};
    void bar() override {};
};

struct D : public A
{
    void foo() override {};
};

int main()
{
    std::shared_ptr<A> a_ptr_1 = std::make_shared<C>();
    std::shared_ptr<A> a_ptr_2 = std::make_shared<D>();
    
    std::shared_ptr<B> b_ptr_1 = /* do something to a_ptr_1 */ nullptr;
    std::shared_ptr<B> b_ptr_2 = /* do same thing to a_ptr_2 */ nullptr;
    assert(!b_ptr_2);
    assert(b_ptr_1);
    b_ptr_1->bar();
    return 0;
}
1

There are 1 best solutions below

0
Patrick Roberts On BEST ANSWER

What you're looking for is std::dynamic_pointer_cast:

std::shared_ptr<A> a_ptr_1 = std::make_shared<C>();
std::shared_ptr<A> a_ptr_2 = std::make_shared<D>();

auto b_ptr_1 = std::dynamic_pointer_cast<B>(a_ptr_1);
auto b_ptr_2 = std::dynamic_pointer_cast<B>(a_ptr_2);
assert(!b_ptr_2);
assert(b_ptr_1);
b_ptr_1->bar();

Try it on godbolt.org