You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在类A中实例化类B并传递A的成员方法至B构造函数遇编译错误求解

问题:类成员函数作为参数传递给另一个类构造函数的编译错误

问题代码

#include <iostream>
using namespace std;
class B
{
    public:
        B(void (*fp)(void))
        {
            fp();
        }
    private: 
};

class A
{
    public:
    void printHelloWorld()
    {
        cout << "Hello World!" << endl;
    } 
    private:
    B ObjB{printHelloWorld};
};
     
int main()
{
    cout << "!!** Program Start **!!" << endl;
    
    A ObjA;
    
    cout << "!!** Program End **!!" << endl;
    return 0;
}  

编译错误

main.cpp:21:27: error: could not convert ‘{((A*)this)->A::printHelloWorld}’ from ‘’ to ‘B’
   21 |     B ObjB{printHelloWorld};
      |                           ^
      |                           |
      |                           <brace-enclosed initializer list>

问题原因

类的非静态成员函数无法直接赋值给普通的void (*)(void)函数指针。因为非静态成员函数隐含了一个指向类对象的this指针作为第一个参数,它的实际签名是void (A::*)(void),和普通无参函数指针类型不匹配。而静态成员函数没有this指针,所以可以直接匹配普通函数指针。

解决方案

方案1:使用静态成员函数

将printHelloWorld声明为静态成员函数,消除this指针的影响,使其类型匹配普通函数指针:

#include <iostream>
using namespace std;
class B
{
    public:
        B(void (*fp)(void))
        {
            fp();
        }
    private: 
};

class A
{
    public:
    static void printHelloWorld() // 改为静态函数
    {
        cout << "Hello World!" << endl;
    } 
    private:
    B ObjB{printHelloWorld};
};
     
int main()
{
    cout << "!!** Program Start **!!" << endl;
    
    A ObjA;
    
    cout << "!!** Program End **!!" << endl;
    return 0;
}  

方案2:用std::function和std::bind绑定this指针

修改B的构造函数接受std::function<void()>类型,通过std::bind将当前对象的this指针和成员函数绑定为可调用对象:

#include <iostream>
#include <functional> // 引入头文件
using namespace std;
class B
{
    public:
        B(function<void()> func) // 改用std::function作为参数类型
        {
            func();
        }
    private: 
};

class A
{
    public:
    void printHelloWorld()
    {
        cout << "Hello World!" << endl;
    } 
    private:
    // 绑定当前对象的this指针与成员函数
    B ObjB{bind(&A::printHelloWorld, this)};
};
     
int main()
{
    cout << "!!** Program Start **!!" << endl;
    
    A ObjA;
    
    cout << "!!** Program End **!!" << endl;
    return 0;
}  

方案3:使用lambda表达式(C++11及以上)

利用lambda捕获this指针,生成可直接调用的匿名函数传递给B的构造函数:

#include <iostream>
#include <functional>
using namespace std;
class B
{
    public:
        B(function<void()> func)
        {
            func();
        }
    private: 
};

class A
{
    public:
    void printHelloWorld()
    {
        cout << "Hello World!" << endl;
    } 
    private:
    // lambda捕获this,调用成员函数
    B ObjB{[this](){ this->printHelloWorld(); }};
};
     
int main()
{
    cout << "!!** Program Start **!!" << endl;
    
    A ObjA;
    
    cout << "!!** Program End **!!" << endl;
    return 0;
}  

方案4:修改B的构造函数接受成员函数指针和对象指针

让B的构造函数同时接收A类的成员函数指针和对象指针,通过对象指针调用成员函数:

#include <iostream>
using namespace std;

// 提前声明A类
class A;

class B
{
    public:
        // 接受A的成员函数指针和对象指针
        B(void (A::*fp)(void), A* obj)
        {
            (obj->*fp)(); // 通过对象指针调用成员函数
        }
    private: 
};

class A
{
    public:
    void printHelloWorld()
    {
        cout << "Hello World!" << endl;
    } 
    private:
    // 传递成员函数指针和当前对象的this指针
    B ObjB{&A::printHelloWorld, this};
};
     
int main()
{
    cout << "!!** Program Start **!!" << endl;
    
    A ObjA;
    
    cout << "!!** Program End **!!" << endl;
    return 0;
}  

内容的提问来源于stack exchange,提问作者Dheeraj Singhal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:40:39