在我当前的项目中,我声明了一个 BaseComponent 类以及从它派生的许多类,这些类被构造为基于复合设计模式的对象树。 BaseComponent包含许多虚拟成员函数。在父类中,这些成员函数通过子对象列表进行交互,在每个对象中递归调用各自的方法。子类根据其目的实现虚函数。
#include <vector>
class BaseComponent
{
public:
virtual void Method(){}
};
class ParentComponent : public BaseComponent
{
private:
std::vector<BaseComponent*> list;
public:
void Method()
{
for (int count=0;count<list.size();count++)
{
list[count]->Method();
}
}
};
class ChildComponent : public BaseComponent
{
public:
void Method()
{
//do something
}
};
问题是,对于我声明的每个虚拟成员函数(它们很多),我必须在父类中编写迭代。此外,可能会有许多不同类型的父类。我的代码显然不能像现在这样可持续。
我考虑使用一些(内部或外部)迭代器模式来避免重复代码的扩散。但是,我真的不想在堆上分配无数的迭代器对象,我想将它们保留在堆栈上。关于如何改进我的代码有什么想法吗?
迭代可以以相对简单的方式抽象出来。
class ParentComponent : public BaseComponent
{
private:
std::vector<BaseComponent*> list;
public:
template <void (BaseCompoment::*PMF)()>
void Run()
{
for (int count=0;count<list.size();count++)
{
(list[count]->*PMF)();
}
}
// Can be deduplicated but only with a macro
void Method1() override { Run<&BaseComponent::Method1>(); }
void Method2() override { Run<&BaseComponent::Method2>(); }
};
但是如果不同的方法有不同的参数怎么办?这也可以做到。
template <auto PMF, typename ... Arg>
void Run(Arg&& ... arg)
{
for (int count=0;count<list.size();count++)
{
(list[count]->*PMF)(std::forward<Arg>(arg)...);
}
}
void Method1( ) override { Run<&BaseComponent::Method1>( ); }
void Method2(int x) override { Run<&BaseComponent::Method2>(x); }
您也不需要使用 PMF,任何类型的可调用都可以使用。
template <auto func, typename ... Arg>
void Run(Arg&& ... arg)
{
for (int count=0;count<list.size();count++)
{
std::invoke(func, list[count], std::forward<Arg>(arg)...);
}
}