-1

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

panc_fab
  • 522
  • 1
  • 7
  • 24
  • 3
    Whats the error message? – tkausl Sep 05 '17 at 08:17
  • 2
    Do you derive `MessageBase` with `public` access? – user7860670 Sep 05 '17 at 08:19
  • I've edited the question including them – panc_fab Sep 05 '17 at 08:21
  • @VTT yes, I use public keyword to derive from MessageBase – panc_fab Sep 05 '17 at 08:22
  • 1
    @panc_fab [MCVE] as usual or it didn't happen. – user0042 Sep 05 '17 at 08:24
  • @user0042 sorry, I'll edit my question now – panc_fab Sep 05 '17 at 08:26
  • Are you using a .h and .cpp for the Interface class? If so, your implementation should be "int Interface::writeMessage(MessageBase *message){ ... }". – kist Sep 05 '17 at 08:38
  • @user0042 now I think it is Minimal complete and verifiable, or not? – panc_fab Sep 05 '17 at 09:37
  • 1
    Nope, it's not complete, and in fact is not even accurate. This cannot be *real* code that produces the *real* problem. `Messagebase` != `MessageBase`, for example. Put it this way. If we can take what you post *verbatim*, copy it to (a) source file(s), attempt to compile it, and produce the error message or runtime conditions you state; *then* it is complete and verifiable. In addition, stripping *all* unnecessary code that is not contributory to the actual problem results in it being *minimal*, complete, and verifiable. – WhozCraig Sep 05 '17 at 15:21
  • @WhozCraig sorry, but this time is the code that I have wrote, and it compiles. Obviously if you put into a main() the last part, you will be able to reproduce the error that I have showed. More than this I don't know what I have to add to this thread. – panc_fab Sep 06 '17 at 07:18
  • And more specifically I've just wrote some "..." to point out the rest of the unnecessary code. So in my opinion this is a minimal, complete and verifiable example. It is simply as it is. I've in fact edited the question by rewriting the code as it is in my IDE, and being more precise on describing the situation. – panc_fab Sep 06 '17 at 07:21
  • @WhozCraig and I do not understand the `Messagebase != MessageBase`. I've rewrote the code, and eliminated the old code from the first version of the question, so now if you read the code, `DerivedMessageX` inherits from `MessageBase` that inherits from `Message`. Then I create a `Message` object pointer and I'll use `new` to create that object as a `DerivedMessageX`. It is all wrote above – panc_fab Sep 06 '17 at 07:24
  • Look at the code you *still* have posted: `template class Messagebase` - note the case of the class name. Now look at the usage later : `class DerivedMessageX : public MessageBase` - That cannot possibly compile. There is no template called `MessageBase` , there is only a template called `Messagebase`. Regardless of all of that, `setValue` is not a member of the `Message` interface, so it should come as no surprise that `element->setValue(x);` introduces a compile error. You need a typed pointer to `DerivedMessageX` to get access to `setValue`. – WhozCraig Sep 06 '17 at 07:32
  • @WhozCraig, Man, it compiles. Trust me or not. I created a template class, and then I use it as baseClass with the type of the new message itself. It is taken from a free book on interface implementation in C++ and it is used to avoid rewrite a lot of code for writing and reading. It uses handlers that, based on the type, calls the type. Again, I can have other problems on the code, but that part compiles and it compiles from a week now. have a look at https://arobenko.gitbooks.io/comms-protocols-cpp/content/message/dispatch_handle.html it describes what I've implemented. – panc_fab Sep 06 '17 at 08:06
  • All I'm saying is *we can't compile **this***. There is no class named `Handler`, There is no template class named `MessageBase`, Every one of these closes with a `}` but is missing the terminating `;`. Belaying *all* of that, what I said in my last comment stands. An object pointer only exposes the members from the pointer, not from the object assigned to said-same. I.e., by assigning your new `DerivedMessageX` to a `Message*`, you're restricted to only `Message` members (and/or base members, which in this case there are none). So your error about `setValue` is completely understandable. – WhozCraig Sep 06 '17 at 08:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/153749/discussion-between-panc-fab-and-whozcraig). – panc_fab Sep 06 '17 at 08:12

1 Answers1

2

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

kist
  • 590
  • 2
  • 8
  • If this used a CRTP as the OP's code (apparently) does, *and* only instantiated instances of derivations, not direct base, thereafter, it may actually prove helpful to the OP. – WhozCraig Sep 05 '17 at 15:23
  • 1
    I posted this answer before the OP added a snippet of his code. That's why the current answers is not up-to-date with the OP code. Of course, I could update this anwer, but I'm not sure if it is worth the time, as we dont know if the OP manage to fix his code or not. – kist Sep 05 '17 at 15:45
  • No, I did not find any solution so far, so I have rewrite overridden methods , one for each type of derived message (I needed that to work in a manner or another for a delivery.. but would be good to understand why it does not work this way, I can update it) – panc_fab Sep 06 '17 at 08:43