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
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.