C ++为每个隐藏类型转换

时间:2017-02-07 23:47:55

标签: c++ foreach type-conversion

我为每个循环迭代一个指针向量。指针是基类。在for each循环中,我使用派生类型作为迭代器的类型。渲染函数仅在某些派生类中定义,但代码编译并运行...如果向量包含指向不具有渲染函数的派生对象的指针(显然),它会崩溃。

for each (DerivedClass* body in myVector)
{
    body->render();
}

我的代码中出现了这个错误,因为当我编写它时,向量只包含指向派生类的指针,但后来我决定重构代码并改变了。

有人能告诉我陷入此错误的正确方法吗?检查空指针似乎不起作用。

2 个答案:

答案 0 :(得分:3)

真的,这里的问题是微软的foreach循环过于宽松。 Microsoft已弃用此扩展,转而使用标准的基于范围的for循环(自C ++ 11开始):

for (DerivedClass* body : myVector) {
    body->render();   
}

这里,循环的头部不会编译,因为它无法从DerivedClass*初始化BaseClass*

关于实际编译,首先,请重新考虑您的设计。您应该编程接口,而不是实现。当某些物品不具有代码气味时,必须依赖这些物体进行渲染。也就是说,可以通过dynamic_cast

来实现
for (auto base : myVector) {
    if (auto derived = dynamic_cast<DerivedClass*>(base)) {
        derived->render();
    }
}

没有C ++ 11(我只能假设缺少标准循环)?您仍然可以使用带索引或迭代器的传统for循环。您还可以更明确地了解我的dynamic_cast示例中的类型。

为了添加一点旋转,有时会出现这种类型的转换很常见的地方(例如,某些编译器实现)。如果确定这是一个很好的设计选择,您可以将此代码包装在算法中。例如,这是它在C#中的外观:

foreach (var body in myVector.OfType<DerivedClass>()) {
    body.render();
}

答案 1 :(得分:1)

如果我理解正确,问题是只有向量中的某些指针指向实现render()类型的对象。如果情况dynamic_cast将执行检查正确类型的技巧。

for (DerivedClass *p : myVector) {
  class_implementing_render *q = dynamic_cast<class_implementing_render>(p);
  if (q) q->render();
}