C++ polymorphism - error passing derived elements to method

106 Views Asked by At

as the title says, I'm stuck with polymorphism issue during the developing of my project. I've already searched online but no responses satisfy my doubts.

So the situation is the following:

  1. defined base abstract class for messages, MessageBase defined an abstract class Message, defined a template class MessageBase that is derived from Message. The different messages are then derived from the MessageBase template class (I'll provide the headers to clarify)
  2. wrote a method writeMessage(Message* message); that accepts a pointer to the base class from which MessageBase and then DerivedMessage(s) inherits.

The classes are defined as follows (report only header files):

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

When I try to call the write message, I perform something like this:

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. 

The exact error is: error: no matching function for call to 'writeMessage(DerivedMessageX* message)'

In my understandings of polymorphism, I know that I describe a base class, containing pure virtual methods, that will be common to all the derived classes, and the derived classes will implement them, along with other specific derived-class methods.

So I wrote the method in order to accept a pointer to a base-class type, that calls a method on that object that is implemented at base-class level. I've done this because, needing only to call a base-class method and because I did not want to rewrite N writeMessage methods, I thought that passing the derived message type created as described above could do the trick.

Can anyone point out where I am wrong?

Thank you guys!

EDIT

As requested, the writeMessage method is defined as follows:

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

and the error says: error: no matching function for call to 'writeMessage(DerivedMessageX* message)'

EDIT rewrote the question in a more complete way. sorry guys

1

There are 1 best solutions below

3
On

There are a lot of things can may be missing if you dont provide a minimal version of your code.

Here is a snippet that does what you need and works:

#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;
};

The output should be:

MessageBase

DerivedMessageX