C++ 派生类中的工厂方法

C++ 派生类中的工厂方法,c++,polymorphism,factory-pattern,dynamic-cast,C++,Polymorphism,Factory Pattern,Dynamic Cast,我有两种消息:MessageA和MessageB,它们都来自抽象类IMessage,包含纯虚方法std::string toString()。因此,我可以使用指向基类的指针将每条消息转换为其字符串表示形式。那很好。但是,我需要以某种方式从字符串构造消息(消息的具体类型),例如: MessageA*msg=[something].fromString(str)。如果给定的字符串不适合构建MessageA,我希望得到NULL。我可以看到完成这项任务的两种方法: a) MessageFactorywi

我有两种消息:
MessageA
MessageB
,它们都来自抽象类
IMessage
,包含纯虚方法
std::string toString()
。因此,我可以使用指向基类的指针将每条消息转换为其字符串表示形式。那很好。但是,我需要以某种方式从字符串构造消息(消息的具体类型),例如:
MessageA*msg=[something].fromString(str)
。如果给定的字符串不适合构建
MessageA
,我希望得到NULL。我可以看到完成这项任务的两种方法:

a)
MessageFactory
with
dynamic\u cast

    class MessageFactory
    {
        IMessage* fromString( const std::string& str );
    };

    ...
    MessageFactory mf;
    MessageA* msg = dynamic_cast< MessageA* >( mf.fromString( str ) );
    if ( msg ) { ... } 
有没有更好的解决办法?我应该改变一下总体设计吗?多谢各位

更新

有时我知道我应该从字符串中得到什么样的信息,即

void sendRequest()
{
 ...
 std::string response;
 MessageA* msg = fromString( response );
 // here i should only check if string is valid for MessageA
}
但有时我不知道会发生什么:

void processMessage( const std::string& str )
{
     IMessage* msg = fromString( str );
     if ( msg )
     {
         MessageA* msgA = dynamic_cast< MessageA* >( msg );
         if ( msgA )
         ...
     } 
}
void processMessage(const std::string&str)
{
IMessage*msg=fromString(str);
如果(味精)
{
MessageA*msgA=dynamic_cast(msg);
if(msgA)
...
} 
}

您可以使从
IMessage
派生的所有类在程序启动时静态地向
MessageFactory
类注册它们自己(或者更确切地说是一个特定的工厂)。这可以通过使用一些静态实例来实现。然后,
IMessage
接口需要有一个纯虚拟方法
canConstructFrom(string&)
,这样当字符串出现时,您将其传递给
MessageFactory
,工厂将发现哪些派生类可以从该字符串构造,并实例化正确的类。

您确实需要它来转换为
MessageA*
<代码>IMessage*不够?这看起来像是滥用。如果您已经知道您想要一个
MessageA
并且只想要一个
MessageA
,那么您可以编写一个直接的解析函数(理想情况下返回
boost::optional
)。多态层次结构似乎没有必要。典型的工厂会返回一条
IMessage*
@KerrekSB,因为我需要接收不同类型的消息。有时我可以期待它的类型,有时不是。消息处理机制应该以不同的方式处理每种消息。您是否可以尝试在接口中声明一个虚拟函数来使用它?然后你就可以通过网络使用它了interface@Kael您可以将差异放入IMessage vía虚拟方法中,因此不需要具体类型。如果您不想将逻辑放入消息类,请使用visitor/double分派模式。谢谢,这是一个很好的解决方案。我的处境和这里描述的一样
void processMessage( const std::string& str )
{
     IMessage* msg = fromString( str );
     if ( msg )
     {
         MessageA* msgA = dynamic_cast< MessageA* >( msg );
         if ( msgA )
         ...
     } 
}