4

我有课

class BarBase {

};

和一个派生的模板类,它存储指向成员函数的指针和指向同一类的对象的指针

template<typename TypeName> class Bar: public BarBase
{
    void ( TypeName::*action ) ( void );
    TypeName* object;
};

我创建实例Bar并将指向它们的指针存储在另一个类的向量中Foo

class Foo {
    private:
        vector<BarBase*> myBars;
    ...
};

现在的问题。Foo 有一个模板函数

template <typename TypeName>
void Foo::foo( TypeName* object , void ( TypeName::*action ) ( void ) )

在此函数中,如何在具有字段且等于此函数参数的myBars元素中找到?如您所见,我无法直接访问这些字段,因为这些字段不是(也不能是).objectactionthis->myBars[i]->actionBarBase

编辑 我可以比较object。我添加一个virtual size_t getObject (){};to并在likeBarBase中覆盖它。然后我比较两个,但我不知道如何转换为数字......Barvirtual size_t getObject (){ return (size_t)this->object; };size_taction

4

2 回答 2

2

最简单的解决方案是使基类多态,并使用dynamic_cast它来确定它是否具有预期的类型:

class BarBase {
public:
    virtual ~BarBase() {}  // virtual function required for polymorphism
};

Bar<TypeName>* bar = dynamic_cast<Bar<TypeName>*>(myBars[i]);
if (bar && bar->object == object && bar->action == action) {
    // it's a match
}

这确实增加了一些支持 RTTI 的开销;在我的脑海中,我想不出任何不增加开销的明确方法来做到这一点。

于 2012-08-29T12:58:10.157 回答
1

如果您不想使用 Mike 变体(我更喜欢他的变体),您可以使用类似的东西。

class BarBase 
{
public:
   virtual ~BarBase() { }
   virtual void* getObject() { return 0; }
   virtual const char* getFunctionName() { return 0; }
};

template<typename T>
class Bar : public BarBase
{
public:
   Bar(T* obj, void (T::*func) (void)):object(obj), action(func)
   {
   }
   virtual void* getObject() { return object; }
   virtual const char* getFunctionName() { return typeid(action).name(); }
   T* object;
   void (T::*action)(void);
};

http://liveworkspace.org/code/d79e33d4597ee209645026b2100330f3

编辑。

对不起。这不是问题的解决方案,因为typeid(&S::action).name()可能等于typeid(&S::other_action).name().

此外,您可以对向量中的所有对象使用dynamic_cast或不使用。static_cast

class BarBase 
{
public:
   virtual ~BarBase() { }
   virtual void* getObject() const { return 0; }
};

template<typename T>
class Bar : public BarBase
{
public:
   Bar(T* obj, void (T::*func) (void)):object(obj), action(func)
   {
   }
   virtual void* getObject() const { return object; }
   T* object;
   void (T::*action)(void);
};

for (auto pos = objects.begin(); pos != objects.end(); ++pos)
{
      if ((*pos)->getObject() == &p)
      {
         auto bar = static_cast<Bar<S>*>(*pos);
         if (bar->action == act)
         {
            // right object founded.
         }
      }
   }

http://liveworkspace.org/code/87473a94411997914906c22ef0c31ace

于 2012-08-29T13:17:15.733 回答