c++ - 在类内部分配函数指针

标签 c++ kernel

我正在编写简单的实验代码来测试将一个类的成员函数分配给另一个类的成员函数指针。我的示例代码没有编译。编译器报错:'&': 对绑定(bind)成员函数表达式的非法操作。

我看到有些人在将指针传递给成员函数时这样做 (&ClassB::printFun)。它对我不起作用,因为 printFun 不是静态成员函数。 我还看到有人使用 std::bind。但是 std 库不适合我,因为我将使用它来编写内核模式代码。我一直在寻找正确的方法来做这件事,有人可以帮我吗?谢谢!

using namespace std;

class ClassA
{
public:
    ClassA(void(*callBack)(int));
    void (*funPtr)(int);
};

ClassA::ClassA(void(*callBack)(int))
{
    funPtr = callBack;
}

class ClassB
{
public:
    void printFun(int a)
    {
        cout << a << endl;
    }
};

int main()
{
    ClassB classB;
    ClassA classA(&classB->printFun);
    classA.funPtr(5);
    return 0;
}

最佳答案

指向函数的指针和指向成员 函数的指针是不同的东西。 您需要一个对象来调用成员函数。

一个指向子函数的指针可以这样声明:

void (ClassB::*ptrPtrintFunc)(int) = &ClassB::printFun;

你可以这样调用它:

ClassB classB;
(classB.*ptrPtrintFunc)(1);

或者这个:

ClassB *ptrClassB = &classB;
(ptrClassB->*ptrPtrintFunc)(2);

您可以做的是使用 std::function 代替旧式函数指针。 您可以将 lambda 函数传递给 std::function,在其中调用类的方法:

#include <iostream>
#include <functional>   // std::function

struct ClassA
{
    using TFunc = std::function<void( int )>; // <-- std::function<void( int )> insted of void(*)(int)
    ClassA( TFunc func) : funPtr( func ) {}
    TFunc funPtr;
};

struct ClassB
{
    void printFun( int a ) { std::cout << a << std::endl; }
};

int main()
{
    ClassB classB;
    ClassA classA( [&classB]( int a ) { classB.printFun(a); } ); // <-- lambda function
    classA.funPtr(5);
    return 0;
}

除了 lambda 函数,您还可以使用 std::bindstd::placholder 作为参数:

ClassB classB;
ClassA classA( std::bind( &ClassB::printFun, &classB, std::placeholders::_1 ) );
classA.funPtr(5);

当然你也可以传递一个简单的函数给std::function

void printFunc( int a ) { std::cout << a << std::endl; }

ClassA classA( printFunc ); 

答案的扩展:不使用 STL 的解决方案

Thanks for the information. I am using std library to print in the experimenting code. But the actual code I am writing is in kernel mode, so I will not have access to std library. I wonder if there is another way to do this.

如果您无论如何都不想使用 STL,您可以考虑使用抽象基类的解决方案。 您需要一个带有抽象回调方法的基类,并且需要 2 个重写抽象回调方法的派生类。回调方法的实现将回调委托(delegate)给函数或类方法。

具有抽象方法 CallBack 的抽象类:

struct CCallBack
{
    virtual void CallBack( int ) = 0;
};

函数指针的实现。重写方法 CallBack 将回调委托(delegate)给函数指针:

struct CCallBackFunc : public CCallBack
{
    typedef void(*TFuncPtr)(int);
    TFuncPtr _funcPtr;
    CCallBackFunc( TFuncPtr funcPtr ) : _funcPtr( funcPtr ) {}
    virtual void CallBack( int a ) override { (*_funcPtr)( a ); }
};

方法函数指针的实现。重写方法 CallBack 将回调委托(delegate)给 对象和方法函数指针:

template < class T >
struct CCallBackMethod : public CCallBack
{
    typedef void(T::*TMethodPtr)(int);
    T &_obj;
    TMethodPtr _methodPtr;
    CCallBackMethod( T &obj, TMethodPtr methodePtr ) : _obj( obj ), _methodPtr( methodePtr ) {}
    virtual void CallBack( int a ) override { (_obj.*_methodPtr)( a ); }
};

两种情况的使用示例:

struct ClassA
{
    ClassA( CCallBack *cb ) : _cb( cb ) {}
    virtual ~ClassA() { delete _cb; }
    CCallBack *_cb;
};

struct ClassB { void printFun( int a ) { std::cout << a << std::endl; } };
void printFun( int a ) { std::cout << a << std::endl; }

int main()
{
    ClassB classB;
    ClassA classA0( new CCallBackFunc( &printFun ) );
    ClassA classA1( new CCallBackMethod<ClassB>( classB, &ClassB::printFun ) );
    classA0._cb->CallBack( 6 );
    classA1._cb->CallBack( 7 );
    return 0;
}

关于c++ - 在类内部分配函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45386009/

相关文章:

python - 我如何有效地将 2d python 列表提供给 C++ 扩展模块

c++ - 在 C++11 或 C++1y 中对非类型模板参数包进行排序?

ios - mach_vm_allocate 和 vm_allocate 有什么区别?

android - 为我的 Android 设备编写简单的内核

c - 如何在 Linux 资源中找到特定系统调用的定义?

c++ - getdepth 函数在 MarchingCube 算法中如何工作?

c++ - 如何在对 vector 中查找元素数

c++ - 大型 C++ 项目的编译时间和内存使用情况?

Windows 内核 ReadProcessMemory()/WriteProcessMemory()?

ubuntu - 在 ubuntu 中导出/安装内核头文件