使用c ++随机选择算法的良好实践

zit*_*eis 6 c++ random design-patterns function-pointers

设置:
必须生成伪随机模式.有几种方法/或算法可用于创建不同的内容.所有算法都会生成一个字符列表(但可能是其他任何东西)......重要的是,它们都返回相同类型的值,并且需要相同类型的输入参数.

必须可以调用GetRandomPattern()方法,该方法每次调用时都会使用随机算法.

我的第一个方法是将每个算法放在它自己的函数中,并在每次调用GetRandompattern()时选择一个随机的算法.但我没有提出另一种选择它们的方式,而不是一个不切实际,丑陋且不灵活的转换案例陈述.

class PatternGenerator{
 public:
  list<char> GetRandomPattern();
 private:
  list<char>GeneratePatternA(foo bar);
  list<char>GeneratePatternB(foo bar);
  ........
  list<char>GeneratePatternX(foo bar);
}
Run Code Online (Sandbox Code Playgroud)

每次调用GetRandomPattern()方法时,选择随机GeneratePattern函数的方法是什么?

或者整个班级的设计应该不同?

非常感谢

Nic*_*s78 9

为每个算法创建一个类,每个算法都对一个生成器类进行子类化.将这些对象的实例放入列表中.随机选择一个并使用它!

更一般地说,如果你开始使用相同的签名创建几个替代方法,那么尖叫着"把我们带入兄弟类"你:)

更新 在指针建议出现后,无法抗拒为面向对象的解决方案争论更多

  • 想象一下,在某些时候你想要打印哪个方法创建了哪个随机的东西.使用对象,它很容易,只需添加"名称"方法或其他东西.如果你得到的只是一个指针,你想如何实现这个目标?(是的,从指针到字符串创建一个字典,嗯...)
  • 想象一下,你发现你有十种方法,其中五种只有参数不同.所以你写了五个函数"只是为了保持代码清除OOP垃圾"?或者你宁愿拥有一个恰好能够存储一些状态的函数(也称为对象?)
  • 我想说的是,这是一个针对某些OOP设计的教科书应用程序.以上几点只是试图充实一点,并争辩说,即使它现在适用于指针,它也不是未来的解决方案.而且你不应该害怕制作与读者交谈的代码(即你的未来,在四周左右)告诉那个人它正在做什么


Eri*_*inn 5

您可以创建一个函数指针数组.这避免了必须创建一大堆不同的类,尽管您仍然必须将函数指针分配给数组的元素.无论你怎么做,都会有很多重复的线条.在您的示例中,它位于GetRandomPattern方法中.在我的,它在PatternGenerator构造函数中.

#define FUNCTION_COUNT 24
typedef list<char>(*generatorFunc)(foo);

class PatternGenerator{
    public:
        PatternGenerator() {
            functions[0] = &GeneratePatternA;
            functions[1] = &GeneratePatternB;
            ...
            functions[24] = &GeneratePatternX;
        }
        list<char> GetRandomPattern() {
            foo bar = value;
            int funcToUse = rand()%FUNCTION_COUNT;
            functions[funcToUse](bar);
        }
    private:
        generatorFunc functions[FUNCTION_COUNT];
}
Run Code Online (Sandbox Code Playgroud)


zit*_*eis 1

感谢您的宝贵意见。我决定使用函数指针,主要是因为我以前不知道它们,它们似乎非常强大,这是一个了解它们的好机会,而且还因为它节省了我很多代码行。

如果我使用 Ruby / Java / C#,我会决定采用建议的策略设计模式;-)

class PatternGenerator{
 typedef list<char>(PatternGenerator::*createPatternFunctionPtr);
public:
 PatternGenerator(){
  Initialize();
   }
 GetRandomPattern(){
  int randomMethod = (rand()%functionPointerVector.size());
  createPatternFunctionPtr randomFunction = functionPointerVector.at( randomMethod );
  list<char> pattern = (this->*randomFunction)();
  return pattern;
  }
private:
  void Initialize(){
   createPatternFunctionPtr methodA = &PatternGenerator::GeneratePatternA;
   createPatternFunctionPtr methodB = &PatternGenerator::GeneratePatternB;
   ...
   functionPointerVector.push_back( methodA );
   functionPointerVector.push_back( methodB );
   }
  list<char>GeneratePatternA(){
   ...}
  list<char>GeneratePatternB(){
   ...}
  vector< createPattern > functionPointerVector;
Run Code Online (Sandbox Code Playgroud)

可读性并不像设计模式解决方案那样差很多,很容易添加新算法,指针算术被封装在一个类中,它可以防止内存泄漏,并且非常快速和有效......