指向不同类函数的函数指针数组

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 on std::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] = &amp;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语言: 函数指针+函数指针数组+指向函数指针数组的指针

在属于不同类的函数中创建指向类的指针

在 C# String 构造函数 String(Char*) 中,为啥构造函数不期望指向字符数组的指针?

C语言基础:指针相关概念(指针的算术运算 指针数组指向指针的指针 传递指针给函数 从函数返回指针 )为啥C 语言不支持在调用函数时返回局部变量的地址?