C++:: 成员函数数组
C++:: Array of Member Functions
我想存储一组不同 Class 的成员函数。在这里重复一下:
要求:
- TypeOf Class
- Class 的实例包含函数
- AddressOf成员函数
- 成员函数参数
我可以储存的东西:
- Class 的实例包含函数
- AddressOf 成员函数。
- 成员函数参数
通常,您不需要存储 Class 类型,因为您可以创建指向 Class 类型的数组指针。我不能这样做的原因是因为我接受的 Class 类型未知且不同。 Class 将用于 Class 类型未知的许多不同项目。
我需要将不同类型的 Class 存储到 Array/List 中,在这种情况下,我只是将 类 的地址存储到数组指针中。
我的问题:当我要调用成员函数时,我需要将Class地址转换为Class类型,但是我不知道要转换成什么类型。
示例代码(未测试 - 真正快速编写):
class A
{
public:
void test1(int i);
};
class B
{
public:
void test2(char c);
};
class Container
{
long* objects;
long* funcs;
int index;
public:
Container()
{
objects = new long[5];
funcs = new long[5];
index = 0;
}
template <class C, typename Types ...>
void Add(C *obj, void (C::*func)(Types ...))
{
objects[index++] = (long)obj;
funcs[index++] = (long)func;
}
typename <Types ...>
void Call(int inx, Types ... values)
{
void (*func)(Types ...) = (void (*)(Types ...))funcs[inx];
// This is where I've got trouble. I don't store the Class
// types, so I don't know what pointer Class type to cast
// the Class Instance address to.
(((*???)objects[inx])->*func)(values ...);
}
};
提前致谢。有什么坑,有什么问题,提前问。
你能在成员函数的签名上稍微限制一下吗?如果是这样,您可以存储绑定函数,而不是分别存储指向对象和成员函数的指针。
template<typename... Args>
class Container {
public:
typedef std::function<void (Args...)> F;
template <class C>
void Add(C* obj, void (C::*func)(Args ...))
{
functions.push_back( [=](Args... args) {(obj->*func)(args...);} );
}
void call(size_t i, Args... args)
{
functions[i](args...);
}
private:
std::vector<F> functions;
};
恕我直言,您的帖子看起来可能是一个有趣的多态编程挑战,但随着额外的要求,"no polymorphism" ...在这种情况下,您将学习更困难的方法。
我必须解决您提出的问题:
When I'm about to call the Member Function, I need to cast the Class
address to the Class type, but I don't know what the type is to cast
to.
曾经被称为 Thunk(当我第一次遇到它时)。在(相对)最近的一次搜索中,我没有在那个名字下找到这个想法(但确实找到了其他几个叫做 thunk 的东西)。我曾经读过的名字的解释是因为 "it encapsulates things that I already thunk"。
请注意,对于 thunk,不需要强制转换(因为您已经对它进行了 thunk)
使用 thunk 作为容器中的对象。
哦,既然你标记了这个 C++,你真的应该使用 std::vector < PVThunk_t >。
// ////////////////////////////////////////////////////////////////////
// Pure Virtual Thunk_t: an abstract base class
class PVThunk_t
{
public:
virtual ~PVThunk_t(){}
virtual void operator()(void* v) = 0;
virtual void exec (void* v) = 0;
};
// pure-virtual requires derived objects to implement both methods
// ///////////////////////////////////////////////////////////////////////
// template class - make it easy to create thunk for any class T
template <class T>
class Thunk_t : PVThunk_t
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
Thunk_t( T* anInstance, // pointer to an instance of class T
void* (T::*aMethod)()) : // pointer to a method of class T, no parameter, returns void
m_instance (anInstance),
m_method (aMethod)
{
assert (m_instance);
asssert (m_method);
}
Thunk_t( T* anInstance, // pointer to an instance of class T
T* (T::*aMethod)()) : // pointer to a method of class T, no parameter, returns T*
m_instance (anInstance),
m_method (aMethod)
{
assert (m_instance);
asssert (m_method);
}
virtual ~Thunk_t() { }
// override operator "()"
virtual void* operator()(void* v) { return((*m_instance.*m_method)(v)); }
// override function "exec"
virtual void* exec(void* v) { return((*m_instance.*m_method)(v)); }
private:
T* m_instance; // pointer to object of T
void (T::*m_method)(void*); // pointer to method attribute of T with void* param
}; // template <class T> class Thunk_t : public PVThunk_t
注意声明 m_instance 和 m_method 指针的正确机制。
如果您需要使用具有可变数量参数的方法,我建议传递一个结构指针(对 Thunk 进行适当的调整或添加。单个方法参数始终是指向结构的指针,其类型或者可以通过调用的方法推断出内容。
我已经很久没有使用这个Thunk了,因为,好吧,多态性在各个方面都是优越的。但是 Thunk 仍然可以编译,所以它可能会工作。
更新 - 注意到虚拟方法不匹配。固定
我想存储一组不同 Class 的成员函数。在这里重复一下:
要求:
- TypeOf Class
- Class 的实例包含函数
- AddressOf成员函数
- 成员函数参数
我可以储存的东西:
- Class 的实例包含函数
- AddressOf 成员函数。
- 成员函数参数
通常,您不需要存储 Class 类型,因为您可以创建指向 Class 类型的数组指针。我不能这样做的原因是因为我接受的 Class 类型未知且不同。 Class 将用于 Class 类型未知的许多不同项目。
我需要将不同类型的 Class 存储到 Array/List 中,在这种情况下,我只是将 类 的地址存储到数组指针中。
我的问题:当我要调用成员函数时,我需要将Class地址转换为Class类型,但是我不知道要转换成什么类型。
示例代码(未测试 - 真正快速编写):
class A
{
public:
void test1(int i);
};
class B
{
public:
void test2(char c);
};
class Container
{
long* objects;
long* funcs;
int index;
public:
Container()
{
objects = new long[5];
funcs = new long[5];
index = 0;
}
template <class C, typename Types ...>
void Add(C *obj, void (C::*func)(Types ...))
{
objects[index++] = (long)obj;
funcs[index++] = (long)func;
}
typename <Types ...>
void Call(int inx, Types ... values)
{
void (*func)(Types ...) = (void (*)(Types ...))funcs[inx];
// This is where I've got trouble. I don't store the Class
// types, so I don't know what pointer Class type to cast
// the Class Instance address to.
(((*???)objects[inx])->*func)(values ...);
}
};
提前致谢。有什么坑,有什么问题,提前问。
你能在成员函数的签名上稍微限制一下吗?如果是这样,您可以存储绑定函数,而不是分别存储指向对象和成员函数的指针。
template<typename... Args>
class Container {
public:
typedef std::function<void (Args...)> F;
template <class C>
void Add(C* obj, void (C::*func)(Args ...))
{
functions.push_back( [=](Args... args) {(obj->*func)(args...);} );
}
void call(size_t i, Args... args)
{
functions[i](args...);
}
private:
std::vector<F> functions;
};
恕我直言,您的帖子看起来可能是一个有趣的多态编程挑战,但随着额外的要求,"no polymorphism" ...在这种情况下,您将学习更困难的方法。
我必须解决您提出的问题:
When I'm about to call the Member Function, I need to cast the Class address to the Class type, but I don't know what the type is to cast to.
曾经被称为 Thunk(当我第一次遇到它时)。在(相对)最近的一次搜索中,我没有在那个名字下找到这个想法(但确实找到了其他几个叫做 thunk 的东西)。我曾经读过的名字的解释是因为 "it encapsulates things that I already thunk"。
请注意,对于 thunk,不需要强制转换(因为您已经对它进行了 thunk)
使用 thunk 作为容器中的对象。
哦,既然你标记了这个 C++,你真的应该使用 std::vector < PVThunk_t >。
// ////////////////////////////////////////////////////////////////////
// Pure Virtual Thunk_t: an abstract base class
class PVThunk_t
{
public:
virtual ~PVThunk_t(){}
virtual void operator()(void* v) = 0;
virtual void exec (void* v) = 0;
};
// pure-virtual requires derived objects to implement both methods
// ///////////////////////////////////////////////////////////////////////
// template class - make it easy to create thunk for any class T
template <class T>
class Thunk_t : PVThunk_t
{
public:
// constructor - takes pointer to an object and pointer to a member and stores
// them in two private variables
Thunk_t( T* anInstance, // pointer to an instance of class T
void* (T::*aMethod)()) : // pointer to a method of class T, no parameter, returns void
m_instance (anInstance),
m_method (aMethod)
{
assert (m_instance);
asssert (m_method);
}
Thunk_t( T* anInstance, // pointer to an instance of class T
T* (T::*aMethod)()) : // pointer to a method of class T, no parameter, returns T*
m_instance (anInstance),
m_method (aMethod)
{
assert (m_instance);
asssert (m_method);
}
virtual ~Thunk_t() { }
// override operator "()"
virtual void* operator()(void* v) { return((*m_instance.*m_method)(v)); }
// override function "exec"
virtual void* exec(void* v) { return((*m_instance.*m_method)(v)); }
private:
T* m_instance; // pointer to object of T
void (T::*m_method)(void*); // pointer to method attribute of T with void* param
}; // template <class T> class Thunk_t : public PVThunk_t
注意声明 m_instance 和 m_method 指针的正确机制。
如果您需要使用具有可变数量参数的方法,我建议传递一个结构指针(对 Thunk 进行适当的调整或添加。单个方法参数始终是指向结构的指针,其类型或者可以通过调用的方法推断出内容。
我已经很久没有使用这个Thunk了,因为,好吧,多态性在各个方面都是优越的。但是 Thunk 仍然可以编译,所以它可能会工作。
更新 - 注意到虚拟方法不匹配。固定