Creating a 'listener' type method - help!


#1

Ok so I have created a listener class like this

class Listener
    {
    public:
        virtual ~Listener() {}
        virtual void sliceCreated();
        virtual void sliceDeleted();
    };
    
    void addListener(Listener *listener);
    void removeListener(Listener *Listener);

added it to a ListenerList

And tried to call it both like this

and

Give the error "call to non-static member function without an object argument"
Does anyone know what I am doing wrong?


#2

Change this:

To this:

You don’t need the “this” pointer, because your methods don’t have parameters.


#3

Ha thanks, I copied it from an example I didn’t fully understand. Sadly you replied before I deleted the OP. Cheers!


#4

You should have left up the post so that anyone else who has this problem can find your posting. To be honest, I failed to see the problem the first time I read it.

It is common when invoking bind to list the this parameter as the first argument after the member function pointer. ListenerList<>::call does not require this parameter (it fills it in for you) but its an easy mistake to make.


#5

I’ll shove it back up now Vinn. I was tearing my hair out for a little while over this. Thanks guys!


#6

Actually the this pointer is not needed because ListenerList<>::call fills it in for you. Even if the methods had parameters, the this pointer would be erroneous.


#7

There is a problem with linking this though.

[quote]Undefined symbols for architecture i386:
“typeinfo for SliceManager::Listener”, referenced from:
typeinfo for SliceEditor in SliceEditor.o
"vtable for SliceManager::Listener", referenced from:
SliceManager::Listener::Listener() in SliceEditor.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)[/quote]

Anyone familiar with this? Virtual member functions should have no definition anyways right?


#8

How so? See the following:

class Foo
{
public:
    class Listener
    {
    public:
        virtual void sliceDeleted (Foo* foo) {}
    };

    void callSomeListenerMethod()
    {
        listeners.call (&Listener::sliceDeleted, this);
    }

private:
    ListenerList<Listener> listeners;
};

In that case, it wouldn’t be erroneous. Although I may be misinterpreting your point? (Eyes are starting to cross from coding!)


#9

Only pure virtual functions should have no definition. (Although pure ones can, I think… maybe only in VS. Not suggested to do it though)


#10

So should my listener functions be pure virtual or?


#11

That depends on the intent of your Listener class - only you can answer that question! :slight_smile:

If not pure virtual, you should put in a blank body.


#12

I need to do some reading I think. Making both functions pure virtual solved my linking error anyways so thats great. Thanks!


#13

No, because if you have more than one virtual function, a listener has to implement ALL of them even if they only care about a subset.


#14

Looking over what I wrote, perhaps I was horribly confused…disregard it!


#15

It’s Monday, after new year’s day - no worries! :smiley:


#16

Ah that makes sense, as if they were all pure some may be left undefined and would cause that linker error again right?

For some reason the listener functions don’t seem to be being called at all. Is there anything I may have missed?

The subclass inherits and registers its self as a listener correctly.

class SliceEditor : public Component, public SliceManager::Listener


#17

Set some breakpoints and trace through it.


#18

Got it, thanks! (Just calling the function in the wrong place by mistake after tinkering with it so much!)