c++ 在类A中创建类B的对象,并在类B的对象的构造函数中传递类A的一个方法[duplicate]

pdkcd3nj  于 2023-01-28  发布在  其他
关注(0)|答案(1)|浏览(163)
    • 此问题在此处已有答案**:

(9个答案)
Pass Member Function as Parameter to other Member Function (C++ 11 ) [duplicate](2个答案)
Passing a pointer to a class member function as a parameter(2个答案)
5小时前关门了。
我试图在一个类中创建另一个类的对象(我可以做到这一点),我想把第一个类的一个方法作为构造函数参数传递给第二个类(我不能做到这一点,我得到编译器错误)。

#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>

代码也可以在此链接上编译https://onlinegdb.com/xB70hwQph
如果我将printHelloWorld作为静态函数,或者将printHelloWorld的定义移出类,代码就可以正常工作。
我正在寻找一个解决这个看起来简单的问题。

wa7juj8i

wa7juj8i1#

不能将非静态方法用作C样式函数指针参数的实参。
原因是为了调用它,您需要一个this指针,这是C函数指针所不能提供的。
您可以将std::function与捕获thislambda一起使用,以实现您所需要的。
然而,由于在声明ObjB时直接初始化它,完整的A可能还没有完全构造(例如通过特定的构造函数),因此直接从B的构造函数调用该方法是有问题的。在您的普通情况下,它可以工作,但想象一下方法printHelloWorld访问一些A成员。
相反,我让B存储std::function,以便以后可以通过invokeF()方法调用它。

    • 代码示例:**
#include <iostream>
#include <functional>

class B
{
public:
//----vvvvvvvvvvvvvvvvvvvvvvvvv----
    B(std::function<void(void)> fp) { m_fp = fp; }
    void invokeF() { m_fp(); }
private:
    std::function<void(void)> m_fp;
};

class A
{
public:
    void printHelloWorld() { std::cout << "Hello World!" << std::endl; }
    void invokeBF() { ObjB.invokeF(); }
private:
//----------vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv----
    B ObjB{ [this]() { printHelloWorld(); } };
};

int main()
{
    std::cout << "!!** Program Start **!!" << std::endl;
    A ObjA;
    ObjA.invokeBF();
    std::cout << "!!** Program End **!!" << std::endl;
    return 0;
}
    • 输出:**
!!** Program Start **!!
Hello World!
!!** Program End **!!

Demo (Godbolt)

相关问题