检查基类中派生模板类的相等性

时间:2012-10-13 12:50:22

标签: c++ templates function-pointers member-pointers

这是我在这个平台上的第一个问题。如果不清楚或者我没有以适当的方式提出要求,我很抱歉。

下面的代码应该使用任何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)) {

}

必须看起来像。

有人知道问题的解决方案吗?或者这种检查不可能吗?

1 个答案:

答案 0 :(得分:0)

将虚拟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,否则会导致内存泄漏,

并且不要在成员变量_ptr的开头使用不定核心 - 如果必须在结尾使用ptr_。一些前导下划线保留给编译器。