2017-09-05 98 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

不,我到目前爲止沒有找到任何解決方案,所以我重寫了重寫的方法,每種類型的派生消息都有一個重寫方法(我需要以某種方式或另一種方式進行交付......但很好理解爲什麼它不這樣工作,我可以更新它) –