My overridden function is not called!

I am trying to make a custom listener based on the observer pattern, like the listeners for Java.

I have this:
1
2
3
4
5
6
7
8
9
10
11
// eventlistener.h
#include <iostream>
using namespace std;

class EventListener
{
   public:
   EventListener(){};
   ~EventListener(){}
   virtual void action(){}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// dataclass.h
#include <iostream>
#include "customeventlistener.h"
using namespace std;

class DataClass
{
   private:
   list<EventListener> listeners;
   int value;
   void fireListeners()
   {
      list<EventListener>::iterator it;
      for(it=listeners.begin(); it!=listeners.end(); it++)
      {
          (*it).action();
      }
   }
  
   public: 
   void addCustomListener(EventListener listener)
   {
      listeners.push_back(listener);
   }

   void setValue(int val)
   {
      this->value = val;
      fireListeners();
   }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//main.cpp
#include <iostream>
#include "dataclass.h"

using namespace std;

class Listener : public EventListener
{
   public: 
   void action()
   {
      cout << "Changed value!" << endl;
   }
};

int main()
{
   DataClass object;
   Listener listener;
   object.addCustomListener(listener);
   object.setValue(5);
   return 0;
}


With the above code I expect that the action() function in the Listener class (declared in main.cpp) shall be called since it is overridden.

But it is the action() function in EventListener that is beeing called.
What am I doing wrong?
You store copies of the listeners instead of pointers to them. Worse, you don't even store full copies, but just the EventListener part of them. This is called object slicing:
http://en.wikipedia.org/wiki/Object_slicing
agree upstair.
list<EventListener*> listeners;
....................................

object.addCustomListener(&listener);
.............................................

you should use the pionter to archive your idea。。。。。。。。。
Thanks for the link Athar Ive never heard of object slicing
Ok, I got it working by storing the objects as pointers.

I also tried to change line 21 in dataclass.h to:
void addCustomListener(EventListener *listener)
and line 19 in main.cpp to:
Listener *listener;

When I run the program, I get a segmentation fault for line 16 in dataclass.h
(*it)->action();

I am trying to understand why, but I cannot. So, why?
It should work if you only changed these three lines (and object.addCustomListener(&listener);).
However, note that with your current approach DataClass will never know when one of the listeners has been destroyed.
Also, the EventListener destructor should be virtual. If it isn't, deleting a derived listener via a EventListener pointer would result in undefined behavior.
Thanks!

I have done a third class, called customevent.h:
1
2
3
4
5
6
7
8
9
10
11
// customevent.h
class CustomEvent
{
   private:
   DataClass dc;

   public:
   CustomEvent(){};
   ~CustomEvent(){}
   void getObject(){}
}


I have also changed EventListener to:
1
2
3
4
5
6
7
8
9
10
11
12
// eventlistener.h
#include <iostream>
#include "customevent.h"
using namespace std;

class EventListener
{
   public:
   EventListener(){};
   ~EventListener(){}
   virtual void action(CustomEvent*){} // the changed line
}


In dataclass.h, I now have this:
1
2
3
4
5
6
7
8
9
void fireListeners()
   {
      CustomEvent event; // added line
      list<EventListener>::iterator it;
      for(it=listeners.begin(); it!=listeners.end(); it++)
      {
          (*it).action(&event); // changed line
      }
   }


My problem: CustomEvent cannot find DataClass. If I include dataclass.h in customevent.h, then it won´t compile because DataClass includes customeventlistener.h which in turn includes customevent.h. So the three files includes each other in a circle-like manner.

How can I work around this?
Last edited on
Forward declare one of the classes and then include them in the .cpp file defining the functions
Topic archived. No new replies allowed.