加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 访问聚合器类中的类之间共享的变量

发布时间:2020-12-16 07:10:23 所属栏目:百科 来源:网络整理
导读:我手头有一个问题,需要针对不同的算法进行非常模块化的设计.例如基于群体的优化算法,如遗传算法,粒子群算法等.这些算法有几种变体,因此我计划将较小的构建块作为抽象类,并让特定的构建块插入. 例如,假设我们有algo1,它可以分为以下子程序 algo1loop{ sub1 ()
我手头有一个问题,需要针对不同的算法进行非常模块化的设计.例如基于群体的优化算法,如遗传算法,粒子群算法等.这些算法有几种变体,因此我计划将较小的构建块作为抽象类,并让特定的构建块插入.

例如,假设我们有algo1,它可以分为以下子程序

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 ();
  }
}

这可以完成,但所有算法都使用算法类的属性,并且算法共享中间变量,我不想给出getter / setter.

我的问题是什么是可用于管理算法之间的共享中间变量的技术.我可以将它作为算法实现参数传递,但中间体和类型的数量可能会从一个实现更改为另一个实现.在这种情况下,创建一个单独的临时变量类或在cpp中创建类似朋友的东西是个好主意吗?注意,中间结果可以是大矢量和矩阵.

如果您需要更多信息或说明,请与我们联系.

注意:我可以通过引入局部和重新计算来省略算法之间共享的变量,但是算法是迭代的并且涉及大矩阵的计算密集因此我想尽可能地减少对象的创建和破坏.

解决方法

我可以建议使用Inverse of Control容器来解决您的问题.

首先,您应该创建几个抽象类以将其保留在容器中:

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容器(请注意它可以以任何方式访问 – 为简单起见我只使用静态指针):

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;
        }
    }
};

另请注意,子例程’Execute()可以请求执行任务所需的任何类型的子例程状态.它甚至可以创建其他状态实例(例如,在算法的后期使用).

现在主要的算法看起来像这样:

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();
    }
 };

…它的用法(请注意它可以用作无状态和状态,具体取决于StateBroker初始化的事实)

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,&s3);
statefulAlgo.Execute();

请注意,Algo课程对子程序状态,州经纪人等一无所知; Sub2Class不知道ISubroutineState1;和StateBroker不关心状态和子程序的实现.

顺便说一下,您可以在https://github.com/ohnefuenfter/cppRestudy(VS2015)查看示例项目

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读