指向不同类函数的函数指针数组
Posted
技术标签:
【中文标题】指向不同类函数的函数指针数组【英文标题】:array of function pointer pointing to functions of a different class 【发布时间】:2015-12-02 21:12:36 【问题描述】:我有一个班级 MyClass。在其中,我想创建一个函数指针数组并用另一个类(MemberClass)的函数初始化该数组。 MyClass 有一个指向 MemberClass 作为成员的指针。 但我得到这个编译时错误 错误 C2440:“正在初始化”:无法从“void (__thiscall MyMemberClass::*)(void)”转换为“F”
//This class has the function that I want to create a function pointer to
class MemberClass
private:
int myValue1;
int myValue2;
public:
int GetValue1() //I want to point to this function from a function pointer in another class
return myvalue1;
int GetValue2() //I want to point to this function from a function pointer in another class
return myvalue2;
//This has array of function pointer that I want to point to member function of another class
Class MyClass
typedef void(*F)();
private:
MemberClass* mclass;
F[] f;
Process();
.cpp
MyClass::MyClass()
f[2] = &MemberClass::GetValue1, &MemberClass::GetValue2 //This line throws error
//error C2440: 'initializing' : cannot convert from 'void (__thiscall MyMemberClass::* )(void)' to 'F'
void MyClass::Processing()
//This is how I am hoping to use the function pointer array
F[Index]();
【问题讨论】:
Save yourself some pain and read this link onstd::bind
.
Also read this piece on method pointers. 我怀疑 SO 能否更好地解释您遇到的问题。
一个简单的函数指针不足以表示一个成员函数。而不是typedef void(*F)()
,你可以在技术上使用typedef void(MemberClass:*F)()
,但整个事情听起来很可疑。成员函数指针很少是解决方案。
【参考方案1】:
F
被声明为指向函数的指针,没有返回 void
的参数。但是您的函数返回int
,并且是MemberClass
的成员函数,而不是普通的普通函数。所以你需要的类型是
typedef int (MemberClass::*F)();
调用它也更有趣:
int result = (mclass->*f[index])();
【讨论】:
【参考方案2】:建议:不要使用方法指针,而是使用 C++11 的 functional
库。
为了简化示例,我稍微删减了 OP 的示例代码。
MemberClass 基本保持不变。我删除了成员变量,因为这些方法现在被硬编码为返回 1 和 2,以便于区分它们。
#include <iostream>
#include <functional>
class MemberClass
public:
int GetValue1()
return 1;
int GetValue2()
return 2;
;
myClass
被撕毁,因为这是行动所在。
class MyClass
private:
我使用std::function
的数组而不是typedef 和typedef 的数组。注意模板参数int()
。这是一个函数数组,不接受任何内容并返回int
。 Magic in std::bind
将提供方法所需的隐藏 this
参数。如果函数有绑定时未知的参数,请使用std::placeholders
在方法的参数列表中为它们节省空间。
由于方法绑定到它们的对象,不再需要存储MemberClass* mclass;
std::function<int()> f[2];
public:
调用函数很简单:索引数组并加上括号。
int Process(int index)
return f[index]();
构造函数要么稍微复杂一点,要么不那么复杂,这取决于你的思想流派。我使用初始化列表是因为它更干净(对我来说,无论如何)并且通常具有性能优势。一方面,您可以将数组换成 std::vector 或大多数其他容器,而无需更改变量定义以外的代码行。
f[0] = std::bind(&MemberClass::GetValue1, mem);
f[1] =...
在构造函数体内仍然是一个选项。
MyClass(MemberClass * mem):
fstd::bind(&MemberClass::GetValue1, mem),
std::bind(&MemberClass::GetValue2, mem)
;
还有一些愚蠢的测试代码来确保这一切正常。为什么?因为每次您不以最简单的形式测试代码时,您都在冒不必要的风险。小事不做,大事也做不成。
int main()
MemberClass c;
MyClass d(&c);
std::cout << d.Process(0) << std::endl;
std::cout << d.Process(1) << std::endl;
一个可剪切和粘贴的块:
#include <iostream>
#include <functional>
class MemberClass
public:
int GetValue1()
return 1;
int GetValue2()
return 2;
;
class MyClass
private:
std::function<int()> f[2];
public:
int Process(int index)
return f[index]();
MyClass(MemberClass * mem):
fstd::bind(&MemberClass::GetValue1, mem),
std::bind(&MemberClass::GetValue2, mem)
;
int main()
MemberClass c;
MyClass d(&c);
std::cout << d.Process(0) << std::endl;
std::cout << d.Process(1) << std::endl;
【讨论】:
谢谢,所以 myclass 中无论如何都需要指向 memberclass 的指针以用于不同的目的。另一个高优先级是当调用 d.process(0) 时,它应该具有最小和最小的性能损失,理想情况下不会比常规函数调用差。你的代码是这样的吗?初始化部分可能很慢,这不是问题。 理论上,为什么一个简单的 f[0] = &MemberClass::GetValue1 不能工作? 最小的运行时命中。当模板专门化时,编译器会处理大部分繁重的工作,之后它应该分解为指针取消引用和通常的函数调用开销。 如果f
的类型正确,f[0] = &MemberClass::GetValue1
可以工作。重要的一点是f[0]
需要知道它是一个指向Class 的成员函数的指针,并且需要一个隐藏的this
参数。我在这里简化了一点,但int GetValue1()
实际上更接近int GetValue1(MemberClass * this)
并且不适合void(*F)();
For more details, read this。有关用法,请参阅 Alan Stokes 的回答。
当然,函数调用中隐藏了this。我可以知道 std::bind 对函数指针的好处吗?我对性能非常敏感以上是关于指向不同类函数的函数指针数组的主要内容,如果未能解决你的问题,请参考以下文章
指针数组 数组指针 函数指针 函数指针数组 指向函数指针数组的指针
梦开始的地方 —— C语言: 函数指针+函数指针数组+指向函数指针数组的指针
在 C# String 构造函数 String(Char*) 中,为啥构造函数不期望指向字符数组的指针?
C语言基础:指针相关概念(指针的算术运算 指针数组指向指针的指针 传递指针给函数 从函数返回指针 )为啥C 语言不支持在调用函数时返回局部变量的地址?