策略模式 - C ++

时间:2015-03-08 21:59:25

标签: c++ design-patterns strategy-pattern

我在向项目实施策略模式时遇到了问题。我创建了所有必要的文件,但是我在main中调用了新的错误,因为我无法将策略初始化为我想要的内容。

Strategy.h

/*All the classes that implement a concrete strategy should use this
The AI class will use this file as a concrete strategy
*/
using namespace std;
class Strategy{
public:
    //Method who's implementation varies depending on the strategy adopted
    //Method is therefore virtual
    virtual int execute() = 0;
 };

我的三个策略 Aggressive.h

#pragma once
#include <iostream>
#include "Strategy.h"

class Aggressive{
   public:
      int execute();

 };

Aggressive.cpp

#pragma once
#include <iostream>
#include "Strategy.h"
using namespace std;

class Aggressive : public Strategy{
  public:
      Aggressive(){}

      int execute(){
        cout << "The defensive player chooses to adopt an aggressive play-                             style" << endl;
        return 0;
    }

};

Defensive.h

#pragma once
#include <iostream>
#include "Strategy.h"

class Defensive{
  public:
     int execute();

};

Defensive.cpp

#include <iostream>
#include "Strategy.h"
using namespace std;

 class Defensive : public Strategy{
    public:
       int execute(){
        cout << "The defensive player chooses to adopt a defensive play-style" << endl;
    }
 };

AI.h

#pragma once
#include "Strategy.h"

class AI{
  public:
    AI();
    AI(Strategy *initStrategy);
    void setStrategy(Strategy *newStrategy);
    int executeStrategy();

};

AI.cpp

#pragma once
#include "Strategy.h"
#include "AI.h"
#include "Aggressive.h"
#include "Defensive.h"


using namespace std;

 class AI{
   private:
       Strategy *strategy;
   public:
      AI(){}
         //Plugs in specific strategy to be adopted
      AI(Strategy *initStrategy){
          this->strategy = initStrategy;
      }
      void setStrategy(Strategy *newStrategy){
          this->strategy = newStrategy;
      }
      //Method that executes a different strategy depending on what 
      //strategt was plugged in upon instantiation.
       int executeStrategy(){
          return this->strategy->execute();
      }
  };

我的临时司机,有新问题 StrategyDriver.cpp

#pragma once
#include "AI.h"
#include "Strategy.h"
#include "Aggressive.h"
#include "Defensive.h"
#include "Random.h"
using namespace std;

int main(){
   AI *ai(new Aggressive());
    ai->executeStrategy();  
}

如果有人发现我的代码存在问题,我们将非常感谢您的帮助。我不完全确定如何将新的ai初始化为已实施的具体策略。

3 个答案:

答案 0 :(得分:1)

根据Christophe的回答,您正在定义 .cpp 文件错误。一般设计方法是

  1. 除非您想要包含特定于实现的标头,否则您只需在相应的 .cpp 中包含相关的 .h

  2. 您可以在 .cpp 文件中定义方法,而不是类本身,除非您没有相应的 .h 文件。有关这方面的更多信息,请点击此处:http://www.cplusplus.com/forum/articles/10627/

  3. .cpp 文件中使用命名空间x 被视为不良做法。如果要包含这样的命名空间,请在头文件中执行此操作。

  4. 可能有更多错误,但你会摆脱很多依赖问题。

答案 1 :(得分:0)

问题是您的策略Agressive不是来自Strategy。因此,您知道Agressive Strategy,但您的编译器不会。

强类型检查规则因此阻止编译器在明显不相关的类型之间盲目转换指针,这里:

AI *ai(new Aggressive());

解决方案是通过让您的策略从Strategy

公开继承来适应您的策略
class Aggressive : public Strategy {
public:
    int execute();

};

当然,你也应该对其他策略做同样的事情。然后您的代码编译没有进一步的问题。

答案 2 :(得分:0)

您尝试两次定义同一个类,一次在头文件中,一次在源文件中。 main只能看到标头中的定义,该定义不会从Strategy继承,因此会出错。

标题需要定义类,声明其所有父类和成员:

#pragma once
#include "Strategy.h"

class Aggressive : public Strategy{
public:
    Aggressive(){}
    int execute();
};

,源文件只定义标头中未定义的任何成员:

// no header guard (#pragma once) - that's just for headers
#include <iostream>
#include "Aggressive.h"  // include the class definition
using namespace std;

int Aggressive::execute(){
    cout << "The defensive player chooses to adopt an aggressive play-                             style" << endl;
    return 0;
}

通过这些更改,类定义将在main中使用的位置可用,因此将允许从Aggressive*到基类指针Strategy*的转换。您需要对其他类进行类似的更改,以便程序能够正确构建和运行。

最后,main想要创建一个AI对象(可以用Strategy*初始化)而不是AI*指针(不能){/ 1}}。

AI ai(new Aggressive());
ai.executeStrategy();