Question

This is my first question on this platform. I am sorry if something is unclear or if I failed to ask in an appropriate way.

The code below should compile with any C++11 Compiler. I tried to reduce it to the minimum. The sense of this code might got lost during this procedure, but it should still be clear that I am trying to do keep a list of classes and corresponding member function to call them all with the same parameter:

#include <iostream>

class Base {
public:
  virtual void Call(int x) = 0;
};

template<class T> class Extended : public Base
{
  public:
  // Constructor.
  Extended(T* ptr, void (T::*memberFunction)(int)) : _ptr(ptr), _memberFunction(memberFunction) { }

  // Call function.
  void Call(int x) {
    (_ptr->*_memberFunction)(x);
  }

private:
  // Pointer to class T.
  T* _ptr;

  // Function pointer.
  void (T::*_memberFunction)(int);

};

class Test1 {
public:
  void Fun1(int x) { std::cout << "Hello " << x << std::endl; }
};

class Test2 {
public:
  void FunX(int x) { std::cout << (x * 2) << std::endl; }
};

class MyList {

 public:
 ~MyList() {
    for (auto it = _list.begin(); it != _list.end(); ++it) {
      delete (*it);
    }
  }

  template <class T> void Add(T* t, void (T::*memberFunction)(int)) {
    _list.push_back(new Extended<T>(t, memberFunction));
  }

  void CallAll(int g) {
    for (auto it = _list.begin(); it != _list.end(); ++it) {
        (*it)->Call(g);
    }
  }

private:
  std::list<Base*> _list;
};


int main() {
  MyList myList;
  Test1 test1;
  Test2 test2;
  myList.Add(&test1, &Test1::Fun1);
  myList.Add(&test2, &Test2::FunX);
  myList.CallAll(100);
}

This works perfect. My problem is that I do not know how to remove a class and member function from the list. Furthermore I do not want the same class and member function to be called twice which is virtually the same problem. I need to check two classes of type Base for equality. I could provide a virtual function which gives me a void pointer.

virtual void* GetPtr() = 0;

But that would only check for equality of the class. I have no clue how to check for equality of function pointers of this class and how

template <class T> void MyList::Remove(T* t, void (T::*memberFunction)(int)) {

}

has to look like.

Does someone know the solution to the problem? Or is this check not possible?

Joe

Was it helpful?

Solution

Add virtual isEqual method to Base.

class Base {
public:
  virtual void Call(int x) = 0;
  virtual bool isEqual(const Base& other) = 0;
};

template<class T> class Extended : public Base
{

  public:
      virtual bool isEqual(const Base& other)
      {
         const Extended* otherPtr = dynamic_cast<const Extended*>(&other);
         return otherPtr != nullptr && otherPtr->_ptr == _ptr && otherPtr->_memberFunction == _memberFunction;
      }

};

And add virtual destructor to Base, otherwise you have memory leak,

And do not use undescore at the beginning of member variable _ptr - if you must use at the end: ptr_. Some leading underscores are reserved for compiler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top