2012-04-10 80 views
0

我有一個基類,C++動態對象施工

class Msg 
{ 
    public: 

    ParseMsg() 
    { 
     ParseMsgData(); 
     ParseTrailer(); 
    } 
    virtual void ParseMsgData() = 0; 
    ParseTrailer(); 

}; 

和派生類,

class InitiateMsg : public Msg 
{ 
    public: 
    void ParseMsgData() { ... } 
}; 


class ReadOperationMsg public Msg 
{ 
    public: 
    void ParseMsgData() { ... } 
}; 


class WriteOperationMsg public Msg 
{ 
    public: 

    void ParseMsgData() { ... } 
}; 

和場景是以下,基於所述數據ParseHeader方法

void UsageFunction(string data) 
    { 
     Msg* msg = ParseHeader(data); 
     ParseMsg 
    } 

    Msg* ParseHeader(string data) 
    { 

     Msg *msg = NULL; 
      .... 
     switch() 
     { 

      case 1: 

       msg = new InitiateMsg(); 
       break; 
      case 2: 
       msg = new ReadOperationMsg{(); 
       break; 
      case 3: 
       msg = new WriteOperationMsg{(); 
       break; 
       .... 

     } 

      return msg;   
    } 

將決定創建哪個對象,所以我在我使用的類之外​​實現了ParseHeader函數。我怎樣才能使Msg類中的ParseHeader函數,然後使用它?

在C#中同樣是在類中定義的方法ParseHeader靜態與和從外部用它來實現,

+3

您正在從基類構造函數中調用虛方法。我*高度*懷疑這將做你想要的。 – 2012-04-10 05:19:00

+1

@AndréCaron:實際上,由於函數是_pure_ virtual,調用將導致_undefined behavior_。 – 2012-04-10 05:34:07

+0

@CharlesBailey:我知道,但即使它只是一個虛擬函數(在這種情況下它不會是未定義的行爲),它仍然不會做OP想要的。 – 2012-04-10 05:36:35

回答

4

您需要Abstract Factory設計模式。它是爲你的場景定製的。
內聯鏈接用一個簡單的例子詳細解釋了比我在這裏更多的細節。

+0

謝謝,我會看到它。 – 2012-04-10 12:36:39

0

那麼,在任何有用的評論之前,你忘記將它們聲明爲public,並忘記在你的類定義中聲明繼承關係。

爲了您的問題,爲什麼不直接聲明ParseHeader函數作爲基類Msg的公共成員方法。如果你這樣做,我不會看到任何問題。

可能存在一些依賴性問題。您需要將該方法作爲Msg中的聲明並將其定義在cpp文件中。例如:

// in Msg.h 
// all other lines are omitted 
public: 
    Msg* ParseHeader(string data); 


// in Msg.cpp 
#include "Msg.h" 
#include "InitiateMsg.h" 
#include "ReadOperationMsg.h" 
#include "WriteOperationMsg.h" 

Msg* Msg::ParseHeader(string data) { 
// ..... 
} 

此外,如果您想要區分具體的基類指針時,它究竟是哪一類。 如果我這樣做,我會在基類中聲明一個emun以記住它。例如:

// Msg.h 
class Msg{ 
public: 
    enum type_t { 
     TBase, 
     TInit, 
     TRead, 
     TWrite 
    } type; 

然後在每個不同的構造方法中,爲類型變量定義一個不同的type_t。因此,您總是可以知道指針指向哪個類,並且可以進行動態類投射而不會遺漏測試。

+0

感謝您查看我的問題。我可以在Msg中使用ParseHeader作爲pulic方法。但是這個parseHeader將決定我需要創建哪個(Derived)Msg?在這種情況下如何處理它? – 2012-04-10 12:36:12

+0

@RajeshSubramanian我不明白你的問題。我個人認爲你的開關可以工作。即使指針是基指針,使用基指針調用的方法也將是派生類中的重寫虛擬方法。其實我在我的項目中使用這種技術,它運作良好。除非我能看到一些錯誤信息,否則我不同意安德烈和查爾斯的看法。 – 2012-04-10 13:31:56