所以我想使用成员函数指针的原因是从一个对象类型未知的地方调用函数,并将所有对象视为void *对象。但我无法这样做,即使理性上看起来函数指针指向子例程的地址,因此对象的类型应该是无关紧要的。我的假设是系统必须做的就是将“this”指针设置为调用成员函数指针的对象。以下是我的代码。我怎样才能实现我想要的目标
class C2
{
public:
int y;
void SetValue(int);
};
void C2::SetValue(int k)
{
cout<<"Setting Value inside C2"<<endl;
y=k;
}
int main()
{
void (C2::*f)(int);
C2 *Ob=new C2();
void *Ob2=(void *)Ob;
f = &C2::SetValue;
((Ob2)->*f)(10);
}
此代码甚至不用VC ++编译器编译,错误为
错误C2296:' - &gt; *':非法,左操作数的类型为'void *'
答案 0 :(得分:1)
问题的简单解决方法就是static_cast
Ob2
到正确的类型,因为你需要知道函数所属的类:
(static_cast<C2*>(Ob2)->*f)(10);
您可以使用模板自动执行此操作:
template <typename Ret, class C, typename... Params, typename... Args>
Ret callMemPtr (Ret (C::*fun) (Params...), void* obj, Args&&... args)
{
return (static_cast<C*>(obj)->*fun)(std::forward<Args>(args)...);
}
//usage
callMemPtr(f,Ob2,10);
然而,这似乎是一种奇怪的方法。你可能最好使用继承或某种形式的擦除。
答案 1 :(得分:1)
理性上似乎函数指针指向子例程的地址,因此对象的类型应该是无关紧要的。
虽然对于指向独立函数的指针以及指向static
成员函数的指针肯定是正确的,但实例成员函数的指针是不同的。指向成员函数的指针可能是数据结构,而不是单个指针,因为它需要支持虚拟调度。
考虑以下代码片段:
#include <iostream>
struct Base {
virtual void foo() = 0;
};
struct Derived : public Base {
virtual void foo() {
std::cout << "Hello" << std::endl;
}
};
typedef void (Base::*MemFn)();
int main() {
Derived d;
MemFn f(&Base::foo);
(d.*f)();
return 0;
}
在上方,f
是指向Base::foo
的指针,但Derived::foo
被调用(demo)。
这就是为什么你不能将函数指针转换为void*
的原因之一。 Void指针是指向数据的指针,而函数指针是指向代码的指针。
答案 2 :(得分:0)
我不知道你为什么要这样,但是你可以去yolo这样做:
#include <iostream>
class test
{
public:
test(){}
void echo(int x)
{
std::cout << "I'm being called: " << x << std::endl;
}
};
int main()
{
test t;
(t.*((void(test::*)(int))&test::echo))(10);
std::cin.get();
return 0;
}