2012-04-10 51 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