C++ 访问聚合器类中类之间共享的变量
我手头有个问题,需要对不同的算法进行非常模块化的设计。例如,基于群体的优化算法,如遗传算法、粒子群算法等。这些算法有几种变体,因此我计划将较小的构建块作为抽象类,并插入特定的构建块 例如,假设我们有algo1,它可以划分为以下子例程C++ 访问聚合器类中类之间共享的变量,c++,oop,design-patterns,C++,Oop,Design Patterns,我手头有个问题,需要对不同的算法进行非常模块化的设计。例如,基于群体的优化算法,如遗传算法、粒子群算法等。这些算法有几种变体,因此我计划将较小的构建块作为抽象类,并插入特定的构建块 例如,假设我们有algo1,它可以划分为以下子例程 algo1 loop { sub1 () sub2 () sub3 () } 为此,我可以创建三个接口,实现将根据它们的实现覆盖它们。所以 //Sub1Class, Sub2Class, Sub3Class are interfaces/abstrac
algo1
loop
{
sub1 ()
sub2 ()
sub3 ()
}
为此,我可以创建三个接口,实现将根据它们的实现覆盖它们。所以
//Sub1Class, Sub2Class, Sub3Class are interfaces/abstract classes
class algo1
{
sub1Class *sub1Obj;
sub2Class *sub2Obj;
sub3Class *sub3Obj;
}
// constructor or setter method to set the implementation
algo1 (Sub1Class *myAlgo1Obj, Sub2Class myAlgo1Obj, Sub3Class myAlgo1Obj)
{
sub1Obj = myAlgo1Obj;
sub2Obj = myAlgo2Obj;
sub3Obj = myAlgo3Obj;
}
doAlgo1
{
loop
{
sub1Obj->algo ();
sub2Obj->algo ();
sub3Obj->algo ();
}
}
这是可以做到的,但是所有算法都使用algo
类的属性,并且算法共享一些中间变量,我不想给出getter/setter
我的问题是,哪些技术可以用来管理算法之间共享的中间变量。我可以将其作为algo方法实现参数传递,但是中间体的数量和类型可能会随着实现的不同而变化。在这种情况下,在cpp中创建一个单独的临时变量类或创建类似于friend
的东西是一个好主意吗?请注意,中间结果可以是大向量和矩阵
如果您需要更多信息或澄清,请告诉我
注:我可以通过引入局部变量和重新计算来省略算法之间共享的变量,但是,这些算法是迭代的,计算量大,涉及到大型矩阵,因此我希望尽可能减少对象的创建和破坏。我可以建议使用控制容器的反转来解决您的问题 首先,您应该创建几个抽象类以将其保存在容器中:
class ISubroutineState {
public:
ISubroutineState() = default;
virtual int getVar1() const = 0;
virtual void setVar1(int v1) = 0;
};
class ISubroutineState1 : public ISubroutineState {
public:
virtual std::string getVar2() const = 0;
virtual void setVar2(std::string& v2) = 0;
};
子程序状态类实现的示例如下:
class SubState1 : public ISubroutineState1 {
int var1;
std::string var2;
public:
int getVar1() const {
return var1;
}
std::string getVar2() const {
return var2;
}
void setVar1(int v1) { var1 = v1; }
void setVar2(std::string& v) { var2 = v; }
};
IoC容器(请注意,它可以以任何允许的方式访问-为了简单起见,我只使用了静态指针):
。。。以及它的用法(请注意,根据StateBroker是否初始化,它可以作为无状态和statefull使用)
s1子类;
s2亚类;
s3亚类;
std::cout-bind(状态);
STD::CUT是一种流行的C++习惯用法,它是使用状态函数对象,通过值传递它们并从最终算法返回它们。我不确定这是否立即适用于这里,但这是一个很好的习惯用法。根据我从您的建议中了解到的情况,我可以传递封装类的对象,该对象保存算法之间共享的变量,但是需要通过访问器方法访问算法之间共享的中间变量。我不想将公共方法公开给这些中间变量。@didierc:@KerrekSB好的,所以这基本上等同于折叠
或减少
。
class StateBroker
{
std::map<const char*, ISubroutineState*> *storage;
public:
StateBroker();
template <class S>
void StateBroker::bind(S* state) {
storage->emplace(typeid(S).name(), state);
}
template <class S>
S* StateBroker::get() const {
auto found = storage->find(typeid(S).name());
if (found == storage->end()) return NULL;
return (S*)found->second;
}
~StateBroker();
};
StateBroker* stateBroker;
class ISubroutine {
public:
virtual void Execute() = 0;
};
class Sub1Class : public ISubroutine {
public:
void Execute()
{
if (stateBroker == NULL)
{
std::cout << "Sub1 called" << std::endl;
}
else {
ISubroutineState1* ss1 = stateBroker->get<ISubroutineState1>();
std::cout << "Sub1 with state called" << std::endl;
ss1->setVar1(1);
ss1->setVar2(std::string("State is changed by Sub1Class"));
std::cout << *static_cast<SubState1*>(ss1) << std::endl;
}
}
};
class Sub2Class : public ISubroutine {
public:
void Execute()
{
if (stateBroker == NULL)
{
std::cout << "Sub2 called" << std::endl;
}
else {
ISubroutineState* ss1 = stateBroker->get<ISubroutineState>();
std::cout << "Sub2 with state called" << std::endl;
ss1->setVar1(2);
std::cout << *static_cast<SubState1*>(ss1) << std::endl;
}
}
};
class Sub3Class : public ISubroutine {
public:
void Execute()
{
if (stateBroker == NULL)
{
std::cout << "Sub3 called" << std::endl;
}
else {
ISubroutineState1* ss1 = stateBroker->get<ISubroutineState1>();
std::cout << "Sub3 with state called" << std::endl;
ss1->setVar1(3);
ss1->setVar2(std::string("State is changed by Sub3Class"));
std::cout << *static_cast<SubState1*>(ss1) << std::endl;
}
}
};
class Algo {
private:
Sub1Class* sub1;
Sub2Class* sub2;
Sub3Class* sub3;
public:
Algo(Sub1Class* s1, Sub2Class* s2, Sub3Class* s3) : sub1(s1), sub2(s2), sub3(s3){}
void Execute()
{
sub1->Execute();
sub2->Execute();
sub3->Execute();
}
};
Sub1Class s1;
Sub2Class s2;
Sub3Class s3;
std::cout << "Stateless algorithm" << std::endl;
Algo mainAlgo(&s1, &s2, &s3);
mainAlgo.Execute();
stateBroker = new StateBroker();
SubState1* state = new SubState1();
stateBroker->bind<ISubroutineState>(state);
stateBroker->bind<ISubroutineState1>(state);
std::cout << "Statefull algorithm" << std::endl;
Algo statefulAlgo(&s1, &s2, &s3);
statefulAlgo.Execute();