首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >战略模式- C++

战略模式- C++
EN

Stack Overflow用户
提问于 2015-03-08 21:59:25
回答 3查看 951关注 0票数 1

我在为我的项目执行一个策略模式时遇到了问题。我创建了所有必需的文件,但是我在main中的新调用出现了一个错误,因为我似乎无法按照我想要的来初始化一个策略。

Strategy.h

代码语言:javascript
运行
复制
/*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;
 };

我的三种策略

代码语言:javascript
运行
复制
#pragma once
#include <iostream>
#include "Strategy.h"

class Aggressive{
   public:
      int execute();

 };

Aggressive.cpp

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
#pragma once
#include <iostream>
#include "Strategy.h"

class Defensive{
  public:
     int execute();

};

Defensive.cpp

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
#pragma once
#include "Strategy.h"

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

};

AI.cpp

代码语言:javascript
运行
复制
#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有问题

代码语言:javascript
运行
复制
#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初始化为已执行的特定策略。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-03-08 22:54:35

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

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

代码语言:javascript
运行
复制
#pragma once
#include "Strategy.h"

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

源文件只定义了头文件中没有定义的任何成员:

代码语言:javascript
运行
复制
// 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*指针(不能)。

代码语言:javascript
运行
复制
AI ai(new Aggressive());
ai.executeStrategy();
票数 1
EN

Stack Overflow用户

发布于 2015-03-08 22:54:48

扩展Christophe的答案,您定义的.cpp文件是错误的。一般的设计方法是

  1. 您只需将相关的.h包含在相应的.cpp中,除非您希望包括特定于实现的标头。
  2. 您可以在.cpp文件中定义方法,而不是类本身,除非您没有相应的.h文件。有关这方面的更多阅读请在这里完成:http://www.cplusplus.com/forum/articles/10627/
  3. 在.cpp文件中使用名称空间x.cpp被认为是错误的做法。如果您希望包含这样的名称空间,请在头文件中这样做。

可能有更多的错误,但您将消除许多依赖问题。

票数 1
EN

Stack Overflow用户

发布于 2015-03-08 22:14:39

问题是您的策略Agressive不是从Strategy派生出来的。因此,您知道Agressive 是一个 Strategy,但编译器不是。

因此,强类型检查规则阻止编译器在明显无关的类型之间盲目转换指针,如下所示:

代码语言:javascript
运行
复制
AI *ai(new Aggressive());

解决方案是通过使策略公开地从Strategy继承来调整您的策略:

代码语言:javascript
运行
复制
class Aggressive : public Strategy {
public:
    int execute();

};

当然,对于其他策略,您也应该这样做。然后,您的代码就会编译,而不会有进一步的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28932415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档