2015-03-08 57 views
1

我有一个问题实施策略模式到我的项目。我创建了所有需要的文件,但是我在主要的新调用中遇到错误,因为我似乎无法将策略初始化为我想要的。战略模式 - C++

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,以实施特定的策略。

+0

你能显示确切的错误信息吗? – Christophe 2015-03-08 22:01:26

+0

我的错误信息是关于新的主要。错误:“Aggressive”类型的值不能用于初始化“AI”类型的实体 – 2015-03-08 22:38:50

回答

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*指针(不能)。

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

尽管如上所述更改了标题和源文件,但我仍然收到相同的错误 – 2015-03-08 23:05:17

+0

@VincentFugnitto:哦,是的,你试图初始化一个指向'AI'的指针而不是一个对象。我没有发现。 – 2015-03-08 23:11:43

+0

是我收到的错误,而不是一个编译错误,只是在新词下的错误是:错误:类型“Aggressive *”的值不能用于初始化类型为“AI *”的实体 – 2015-03-08 23:11:49

0

问题是您的策略Agressive不是从Strategy派生。所以你知道AgressiveStrategy但你的编译器不。

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

AI *ai(new Aggressive()); 

的解决方案是通过使他们从Strategy公开继承来适应你的策略:

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

}; 

当然,您也应该对其他策略也一样。你的代码然后编译没有更多的问题。

+0

我对每个策略的每个.h和.cpp文件执行了:public Strategy,但是我仍然得到同样的错误在我的新的主要。我有错误,错误:“Aggressive”类型的值不能用于初始化“AI”类型的实体 – 2015-03-08 22:38:25

1

上克里斯托夫的答复扩展,您要定义的.cpp文件错误。一般的设计方法是

  1. 你应该只需要包括相应的的.cpp相关.H,除非你想包括执行特定的头文件。

  2. 你定义在的.cpp文件方法,而不是类本身,除非你没有相应的.H文件。更多关于这方面的阅读来到在这里完成:http://www.cplusplus.com/forum/articles/10627/

  3. 它被认为是不好的做法有使用命名空间X的.cpp文件。如果你想包含这样的名字空间,在你的头文件中执行。

有可能是更多的东西错了,但你会摆脱很多的依赖性问题。