如何根据列表中的对象的运行时类型而不是基本类型对其进行操作

How do I operate on objects in a list based on their run time type, not their base type?

本文关键字:类型 操作 列表 何根 对象 运行时      更新时间:2023-10-16

在我的程序中,我有一个基类Object和一个向量。我想对每个Object*执行一个操作,但是该操作依赖于Object*最派生的类。因此,我使用访问者模式。然而,我发现访问者模式导致了大量的耦合;每当我添加一个新的Object派生类时,我必须更改基Visitor和从Visitor派生的每个类。

有没有一种更简单的方法可以根据对象的运行时类型对其列表执行操作,而不会导致如此高的耦合?

class Object
{
  virtual void action() = 0;
  /* ... */
};
void objectAction(Object * o) { o->action(); }
int main()
{
  std::vector<Object*> v;
  std::for_each(v.begin(), v.end(), objectAction);
}

现在只需在每个派生类中实现action

我将在字里行间阅读,并猜测您的大多数派生对象都有其唯一的成员函数,并且不存在于任何其他派生对象中,这就是为什么您不想将它们添加到基类中。

可以使用dynamic_cast查看指针是否属于派生程度最高的类,如果属于,则调用该函数。

MyBase * pBase = *iterator;
MyDerived * pDerived = dynamic_cast<MyDerived *>(pBase);
if (pDerived != NULL)
    pDerived->UniqueMethod();

任何虚拟函数都可以…

Object* obj;
//...
obj->doOperation();

您的抽象基类(称为"object")提供了每个继承类必须实现的抽象实现框架。您只需在基类的每个实例上调用适当的方法。类似这样的东西(在C#中,因为我的C++相当腐蚀,但你应该明白):

public abstract class Widget
{
  public void MandatoryMethod() ; // no method implementation
}
public class FooConcreteWidget : Widget
{
  public override void MandatoryMethod()
  {
    // some concreted implementation
  }
}
public class BarConcreteWidget : Widget
{
  public override void MandatoryMethod()
  {
    // another concrete implementation
  }
}
...
List<Widget> Widgets = GetSomeWidgets() ;
for ( Widget widget in Widgets )
{
   widget.MandatoryMethod() ;
}

这就是它的全部。