Проверка на равенство производных шаблонных классов в базовом классе

Это мой первый вопрос на этой платформе. Прошу прощения, если что-то неясно или я не смог спросить соответствующим образом.

Код ниже должен компилироваться с любым компилятором C ++ 11. Я пытался свести его к минимуму. Смысл этого кода может быть потерян во время этой процедуры, но все же должно быть ясно, что я пытаюсь сохранить список классов и соответствующую функцию-член, чтобы вызывать их все с одним и тем же параметром:

#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);
}

Это работает отлично. Моя проблема в том, что я не знаю, как удалить класс и функцию-член из списка. Кроме того, я не хочу, чтобы один и тот же класс и функция-член вызывались дважды, что является практически одной и той же проблемой. Мне нужно проверить два класса типа Base на равенство. Я мог бы предоставить виртуальную функцию, которая дает мне пустой указатель.

virtual void* GetPtr() = 0;

Но это только проверило бы на равенство класса. Я понятия не имею, как проверить на равенство указателей на функции этого класса и как

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

}

должен выглядеть так.

Кто-нибудь знает решение проблемы? Или эта проверка невозможна?

Джо

2

Решение

Добавьте виртуальный метод isEqual в 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;
}

};

И добавить виртуальный деструктор Baseиначе у вас утечка памяти,

И не используйте undescore в начале переменной-члена _ptr — если вы должны использовать в конце: ptr_, Некоторые ведущие подчеркивания зарезервированы для компилятора.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]