我有一个班级
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
元素中找到字段object
和action
等于此函数的参数?正如您所看到的,我无法直接访问this->myBars[i]->action
这样的字段,因为这些字段不是(也可能不是)BarBase
的成员。
修改
我可以比较object
。我将virtual size_t getObject (){};
添加到BarBase
并在Bar
中覆盖virtual size_t getObject (){ return (size_t)this->object; };
。然后我比较两个size_t
,但我不知道,如何将action
转换为数字...
答案 0 :(得分: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;在我的头脑中,我无法想到任何明确的方法来做到这一点,而不会增加开销。
答案 1 :(得分: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()
。
此外,您可以对{vector>中的所有对象使用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