如何根据列表中的对象的运行时类型而不是基本类型对其进行操作
How do I operate on objects in a list based on their run time type, not their base type?
在我的程序中,我有一个基类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() ;
}
这就是它的全部。
相关文章:
- 逐位操作的隐式类型转换
- 像union_这样的 Boost.Geometry 操作如何处理浮点类型的基本不精确性?
- 为什么 std::lerp 不适用于任何已实现所需操作的类型?
- C++:将值赋值给原始数据类型(例如布尔值)是原子操作吗?
- 标量类型的特征模板无法编译固定大小的子矩阵操作
- 为表示一个或多个操作的C++函数的int参数寻找类型安全的替换
- 对于 CPU 无法原子操作的类型,std::atomic 有什么意义?
- "+=" 操作在类型之间不起作用 std::复杂<double>和__complex__双精度
- 使用用户定义的操作隐式转换为类型
- 元数据操作失败LNK2022错误 (8013118D):重复类型中的布局信息不一致 (选择设备参数):(0x020002
- 是否有可能具有放入容器的移动操作的类型?
- 在 Fortran 中泛化特定声明类型的操作
- 为什么对小于 4 个字节的整数类型的位操作会发生意外行为?
- 对标准类型使用原子操作
- POD 类型的原子按位操作
- CAN模板类型推理考虑原始操作类型转换
- 是浮点操作,导致IEC 559/IEEE 754浮点类类型的无限行为
- STD ::向量迭代器类型和允许的操作
- 布尔类型操作
- 增强融合变换类型操作和as_vector