2017-09-05 14 views
-1

タイトルとして、プロジェクトの開発中に多形性の問題が残っています。私はすでにオンラインで検索しましたが、私の疑問を解決する回答はありません。だから、状況は以下の通りですC++ポリモーフィズム - 派生した要素をメソッドに渡すときにエラーが発生する

  1. は、メッセージのための基本抽象クラスを定義し、MessageBase は抽象クラスのメッセージを定義したが、メッセージから導出されたテンプレートクラスMessageBaseを定義しました。次に、異なるメッセージをMessageBaseテンプレートクラスから派生させます(私は明確にするためにヘッダーを提供します)。
  2. がメソッドwriteMessage(Message * message)を書きました。 MessageBaseからDerivedMessage(s)が継承する基底クラスへのポインタを受け取ります。

    //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(); 
        } 
    } 
    

    私は書込みメッセージを呼び出そうとすると、私はこのような何かを実行:

    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 *メッセージ)に該当する機能「

EDIT より完全に質問を書き直しました方法。ごめんなさい

+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

これはOPのコードとしてCRTPを使用した場合(明らかに)、その後直接ベースではなく、インスタンス化された派生インスタンスのみがOPに役立つ可能性があります。 – WhozCraig

+1

OPがコードのスニペットを追加する前に、この回答を掲載しました。そのため、現在の回答はOPコードで最新ではありません。もちろん、私はこのアンカーを更新することができますが、OPが彼のコードを修正するかどうかわからないので、時間の価値があるかどうかは分かりません。 – kist

+0

いいえ、これまでのところ解決策が見つかりませんでした。したがって、派生したメッセージの種類ごとに1つずつオーバーライドされたメソッドを書き直しました(配信のために別の方法で動作する必要がありましたが、この方法では動作しません、私はそれを更新することができます) –

関連する問題