2017-09-05 100 views
-1

正如标题所说,我在项目开发过程中遇到了多态性问题。我已经在网上搜索,但没有回应满足我的疑惑。C++多态 - 错误将派生元素传递给方法

因此,情况如下:对于消息

  1. 定义的基抽象类,MessageBase 定义一个抽象类的消息,定义了从消息来源的模板类MessageBase。然后从MessageBase模板类派生不同的消息(我将提供头文件来阐明)
  2. 写了一个方法writeMessage(Message * message);它接受一个指向基类的指针,MessageBase然后继承DerivedMessage。

的类定义如下(报告仅头文件):

//Message.hh 
class Message{ 

public: 
     Message(); 

protected: 
     virtual void write() = 0; 
     virtual void read() = 0; 
     virtual void handle() = 0;  
} 

//MessageBase.hh 
template<typename MessageType> 
class Messagebase : public Message { 
protected: 
    Handler handler; 
public: 
//define the three methods of base class 
void write() { handler.write(static_cast<MessageType&>(*this);} 
} 

void read() { handler.read(static_cast<MessageType&>(*this);} 
} 

void handle() { handler.handle(static_cast<MessageType&>(*this);} 
} 

}; 

//class DerivedMessageX.hh 

class DerivedMessageX : public MessageBase<DerivedMessageX> { 
public: 
... 
void setValue(int x); 

//other methods of that type of message 
} 

class Interface{ 

... 
... 
public: 
    void writeMessage(Message* message){ 
     message->write(); 
    } 
} 

当我尝试调用write消息,我执行这样的事情:

Message* element = new DerivedMessageX(); //where DerivedMessageX is one of the derived message types 

element->setValue(x); //this raise an error, setValue is not part of class Message 

interface->writeMessage(element); //here the compiler does not recognize that my "element" is of base type MessageBase and so it tells that it cannot find any prototype to call. 

确切错误是:错误:没有匹配函数调用'writeMessage(DerivedMessageX * message)'

在我对多态的理解中,我知道我描述了一个基类,它包含纯虚拟方法,它将对所有派生类都是通用的,并且派生类将与其他特定派生类方法一起实现它们。

所以我编写了这个方法来接受一个指向基类类型的指针,该指针调用基类级别实现的该对象的方法。我这样做是因为,只需要调用基类方法,并且因为我不想重写N个writeMessage方法,我认为传递如上所述创建的派生消息类型可以实现上述功能。

任何人都可以指出我错在哪里?

谢谢你们!

EDIT

按照要求,的WriteMessage方法被定义如下:

int writeMessage(MessageBase* message){ 
    message->write();   // the method write() is base class level 
} 

和误差表示:错误:对呼叫“的WriteMessage(DerivedMessageX *消息)没有匹配的功能'

编辑 重写了一个更完整的问题 办法。抱歉,家伙

+3

请告诉我的错误信息? – tkausl

+2

你是否用'public'获得'MessageBase'? – VTT

+0

我编辑了包括他们的问题 –

回答

2

如果你不提供最小版本的代码,有很多东西可能会丢失。

这里是一个片段,做你需要什么,工作原理:

#include <iostream> 

class MessageBase 
{ 
    public: 
    // CTOR 
    MessageBase(){}; 

    virtual void printType(){ 
     std::cout << "MessageBase" << std::endl; 
    }; 

}; 

class DerivedMessageX: public MessageBase 
{ 
    public: 
    // CTOR 
    DerivedMessageX():MessageBase(){}; 

    void printType(){ 
     std::cout << "DeviredMessageX" << std::endl; 
    }; 
}; 


class Interface 
{ 
    public: 
    Interface(){}; 

    void writeMessage(MessageBase *elem){ 
     elem->printType(); 
    }; 
}; 

int main() 
{ 
    Interface interface; 

    MessageBase *base = new MessageBase(); 
    MessageBase *derived = new DerivedMessageX(); 


    interface.writeMessage(base); 
    interface.writeMessage(derived); 

    return 1; 
}; 

输出应该是:

MessageBase

DerivedMessageX

+0

如果这使用CRTP作为OP的代码(显然),*和*仅仅实例化派生实例,而不是直接基础,此后,它可能实际上证明对OP有帮助。 – WhozCraig

+1

我在OP添加他的代码片段之前发布了这个答案。这就是为什么当前答案与OP代码不同步的原因。当然,我可以更新这个版本,但我不确定是否值得花时间,因为我们不知道OP是否设法修复他的代码。 – kist

+0

不,我到目前为止没有找到任何解决方案,所以我重写了重写的方法,每种类型的派生消息都有一个重写方法(我需要以某种方式或另一种方式进行交付......但很好理解为什么它不这样工作,我可以更新它) –