将基类指针强制转换为派生类(引用)

时间:2017-01-06 21:39:12

标签: c++

我正在上课,其中包含一个方法的重载版本很少。每个版本都有一个参数 - 对象 - 该对象始终从一个基类派生。 (没有采用Base类参数的方法。)

class Base { ... }
class Object1 : public Base { ... }
class Object2 : public Base { ... }
class Object3 : public Base { ... }

class T
{
    // ... 
    do_sth(const Object1& obj);
    do_sth(const Object2& obj);
    do_sth(const Object3& obj);
    // ...
}

然后我用unique_ptr创建指向Base类的向量,包含(仅)派生类对象。

std::vector<std::unique_ptr<Base>> vect;    // then some push_backs

现在我想为T::do_sth中的每个对象调用vect,如下所示:

for (auto& object : vect)
    T_obj.do_sth(*object);

然而,这种方式是不可能的,因为render(*object)调用do_sth(Base),甚至不存在(并且这不是通缉行为)。我尝试用几个不同的(使用转换)替换该行,但我的尝试都没有成功。如何解决?

1 个答案:

答案 0 :(得分:4)

鉴于要求&#34;不修改任何Object类,没有虚拟功能&#34;从评论中,您的第一个解决方案似乎是dynamic_cast,因此使用:

for (auto const& uObj : vect) {
    if(auto *obj = dynamic_cast<Object1 const *>(uObj.get()))
        T_obj.do_sth(*obj);
    else if(auto *obj = dynamic_cast<Object2 const *>(uObj.get()))
        T_obj.do_sth(*obj);
    else if( /* ... */)
        // And so on.
}

这通常是我使用一次性宏的地方 - 使用风险自负。

#define DYNAMIC_CALL_DO_STH(Type) \
    if(auto *obj = dynamic_cast<Type const *>(uObj.get())) \
        T_obj.do_sth(*obj)

for (auto const& uObj : vect) {
    DYNAMIC_CALL_DO_STH(Object1);
    else
    DYNAMIC_CALL_DO_STH(Object2);
    else
    DYNAMIC_CALL_DO_STH(Object3);
}

#undef DYNAMIC_CALL_DO_STH