2015-03-08 120 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文件。如果你想包含這樣的名字空間,在你的頭文件中執行。

有可能是更多的東西錯了,但你會擺脫很多的依賴性問題。