我试图写一个消息处理程序,其基类是1-Handler基类2处理程序工厂,为适当的消息类型生成适当的处理程序3和消息的通用基类他们的代码是这样的:#include <map>#include<iostream>//Base Handlertemplate<class MSG>class Handler{ MSG message;public: Handler(MSG message):message(message){ } virtual void handle() = 0; MSG getMessage() { return message; }};//Base Handler Factorytemplate<class MSG>class HandlerFactory {public: virtual Handler<MSG> * create(MSG & message) = 0;};//Base messagetemplate<class T>class Message{ T messageType;public: T getMessageType() { return messageType; } void setMessageType(T messageType_) { messageType = messageType_; }};//然后,根据消息类型,我为每个基类编写子类://my custom typesenum MessageType{ ANNOUNCE, KEY_SEND, KEY_REQUEST};//my first custom message formatclass MyMessage_1 : public Message<MessageType>{ //...};//my first custom handlerclass MyMessageHandler_1 : public Handler<MyMessage_1>{public: MyMessageHandler_1(MyMessage_1 &message_): Handler<MyMessage_1>(message_) { } void handle(){}};//my custom handler factoryclass MyHandlerFactory : public HandlerFactory<Message<MessageType> > { Handler<Message<MessageType> > *value;public: MyHandlerFactory(){}; Handler<Message<MessageType> > * create(Message<MessageType> & message){ switch (message.getMessageType()) { case ANNOUNCE: MyMessage_1 t1; value = new MyMessageHandler_1(t1);//error here break; //etc. etc. default: value = 0; break; }; return value; };};//放一个main,这样您就可以轻松编译它int main(){}问题是,当我在switch-case子句中尝试为我的一个自定义消息类创建处理程序的实例时,出现以下错误:templateArgList.cpp: In member function ‘virtual Handler<Message<MessageType> >* MyHandlerFactory::create(Message<MessageType>&)’:templateArgList.cpp:86:37: error: cannot convert ‘MyMessageHandler_1*’ to ‘Handler<Message<MessageType> >*’ in assignment我的印象是:Handler<Message<MessageType> > *可以强制转换为以下形式:MyMessageHandler_1-> Handler<MyMessage_1> ^ | `Message<MessageType>` which finally gives me: `Handler<Message<MessageType> >` :P我错了吗?我当然是,为什么我会收到上述错误呢:))我只是不知道为什么以及如何解决它。因此,如果您能帮助我,我将不胜感激。非常感谢您的帮助 最佳答案 这是一个非常简单的程序,类似于您所做的,但是没有嵌套模板,因此可以理解:#include <vector>class A {};class B : public A {};int main() { std::vector<A>* va; va = new std::vector<B>;}确实,g ++给出了错误:error: cannot convert ‘std::vector<B>*’ to ‘std::vector<A>*’ in assignment这应该很清楚-即使B从A继承,A的向量也不同于B的向量。为了能够利用继承,您必须具有指向相关对象的指针。例如:int main() { std::vector<A*> va(3); for (int i=0; i<3; ++i) { va[i] = new B; }}这里的类比是:std::vector< > ----> Handler< >A ----> Message<MessageType>B ----> MyMessage_1顺便说一句,您是否意识到在MyMessageHandler_1和Handler 中都定义了一个名为message的变量?这将导致MyMessageHandler_1 :: message隐藏Handler :: message。我不确定这是否是您想要的。另外,您可能希望研究the Twisted package for Python,因为它可能非常适合您正在构建的应用程序。 (如果您不介意使用Python。)问题:“有任何建议更改我的代码吗?”响应:好吧,我将尝试删除模板并享受继承的力量。 Handler类可以接受Message对象(或引用或指针),因为这两个都是基类。 HandlerFactory的创建还将接受一个Message对象。然后,可以继续使用具有Message类型成员变量的enum MessageType类,并使用HandlerFactor内部的switch确定要创建的正确的Handler派生类。或者代替枚举,您可以通过向NewHandler()添加“ Message”函数来进一步利用继承,该函数在Message中是纯虚拟的,并在派生类中定义。这样,您就不需要切换了-每种类型的消息都知道它需要什么Handler,并且该因子只需调用message->NewHandler()即可。...由于我不确定项目的去向,因此很难确定是否需要使用模板。但是,根据经验,最好是在以下情况下使用模板:(a)您想要对不同类型使用等效的代码块,并且(b)无法使用继承来完成模板。 std::vector<>是一个很好的例子-std::vector<int>和std::vector<float>的行为是相同的,但是int和float的行为没有任何共同的基础,所以不要重写VectorI和VectorF的代码,则要求编译器重写代码。到目前为止,您似乎可以利用继承来执行所需的操作。它还具有使其他人也更容易阅读您的代码的额外好处。 :)
09-08 01:04