How to subclass Message


#1

Hi!

Newbie-question:

How can I create a subclass of juce::Message?

I did it like this:

class Mess : public Message
{
  public:
    int intParameter1;
    int intParameter2;
    int intParameter3;
    MemoryBlock *pointerParameter;

    Mess(int ip1, int ip2, int ip3, MemoryBlock *ip4)
    {
        intParameter1 = ip1;
        intParameter2 = ip2;
        intParameter3 = ip3;
        pointerParameter = ip4;
    }
};

But when I try to initialize another class that uses it, the compiler throws Allocating an object of abstract class type 'OSC_Listener' at:

​m_OSCListener = new OSC_Listener(*this);

The OSCListener class looks like this:

class MainContentComponent;
class OSC_Listener: public Thread, private MessageListener
{
public:
    OSC_Listener(MainContentComponent& owner_);
    ~OSC_Listener();
   
    void handleMessage (const Mess& message); 

    void run();

protected:

private:
   ScopedPointer <MemoryBlock>      messageData;
   ScopedPointer <DatagramSocket>   socket;

   MainContentComponent& owner;

   JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSC_Listener);
};

What can I do?

Thanks alot!


#2

Generally: Allocating an object of abstract class type 'X'

This means there are pure virtual methods in the classes OSC_Listener inherits which you haven't implemented. 

The IDE might helpfully point them out if you look at the detail of the error message. 

However, in your case it's because you need to do this: 

void handleMessage(const Message & msg);

Not Mess.  

Then you probably need to (carefully) dynamic_cast<Mess> the Message.  If you know you will only get Mess's passed rather than Messages then you might ignore the possible exception that dynamic_cast<> will throw.  I'd be tempted to do this: 

void handleMessage(const Message & msg) override {
 Mess m* = dynamic_cast<Mess *>(& msg); 
 jassert(!m); /* Got a nullptr - was passed something other than a mess. */ 
 if (m) { 
   .... some code to process message 
 } 
}

Note: 

  • Safe use of dynamic_cast<>.  If you don't use a pointer then doing it safely involves a try and catch block (which might be the most C++ way ...). 
  • The use of override keyword which will highlight problems with overridden methods faster.  

And I'd be careful with passing a pointer to a memory block around in a message, particulary anything that's going to be handle asychronously.  You'll need to make sure it's still valid when it gets processed. 

If that's an issue have a look at ReferenceCountedObject which kinda solves that problem.