【问题标题】:Passing member function to another object's member function C++将成员函数传递给另一个对象的成员函数 C++
【发布时间】:2015-03-24 18:35:49
【问题描述】:

我在尝试将函数作为参数传递给另一个对象的函数时遇到问题。我很清楚有许多类似的主题,但我要么无法让他们的解决方案发挥作用,要么无法理解。

class foo
{
public:
    void func1(void (*Drawing)(void));

    template<class T>
    void func2(void (T::*Drawing)(void));
};

class bar
{
private:
    foo myFoo;
    void Drawing();
    void func3() {
        // Attempt 1
        myFoo.func1(Drawing);

        // Attempt 2
        myFoo.func2<bar>(&bar::Drawing);
    }
};

所以在我的第一次尝试中,我得到了你无法将 void (bar::*)(void) 转换为 void (*)(void) 的错误,然后我发现其中有正常的函数指针和成员函数指针。

尝试 2 是我克服这个问题的微弱尝试,但我现在得到了未解决的外部问题...

那么我怎样才能成功地将我的Drawing() 成员函数从另一个对象传递给另一个函数呢?

【问题讨论】:

  • 使用函数对象,而不是函数指针。
  • 您收到未解决的符号错误,因为您没有提供func2 的定义。
  • 你能发布完整的链接器错误信息吗?
  • 我不明白你应该如何在foo 中使用&amp;bar::Drawing,因为它是一个私有成员函数。即使给定了指向成员的指针,编译器也不会让你调用它。无论如何,如果没有实例就无法调用它,因此您还需要将 *this 传递给函数。
  • @AustinMullins 可以在bar使用,访问控制只保护名字。它在foo::func2 中有不同的名称。想象一下,如果它像你描述的那样工作——你甚至不能返回对私有成员变量的引用。

标签: c++ function-pointers member-function-pointers member-functions


【解决方案1】:

问题是您不能将bar::Drawing 视为void (*)(void) 函数,因为它是一个非静态方法,因此需要一个对象(将使用this 上下文)

假设您可以使用 c++11,一个解决方案是使用 std::bind 并稍微修改您的 foo 定义:

class foo
{
    public:
    void func1(std::function<void(void)> Drawing)
    {
        Drawing(); // or do whatever you want with it
    }
};

那你就可以了

void bar::func3() {
    myFoo.func1(std::bind(&bar::Drawing, this));
}

使许多潜在用途有效

int main()
{
    bar myBar;
    myBar.func3();

    foo myFoo;
    myFoo.func1([](){ printf("test\n"); });
    return 0;
}

【讨论】:

  • 这成功了!非常感谢你。说如果我不使用C++11,有没有其他方法可以解决这个问题?
【解决方案2】:

我猜您遗漏了有关您要完成的任务的重要细节。但是,以下内容应该会让您对需要做什么有所了解。

代码

#include <iostream>

class foo
{
public:
    void func1(void (*Drawing)(void))
    {
        std::cout << "func1\n";
    }

    template<class T>
    void func2(T* instance, void (T::*fn)(void))
    {
        std::cout << "func2: ";
        (instance->*fn)();
    }
};

class bar
{
public:
    bar()
    {
        func3();
    }

private:
    foo myFoo;

    void Drawing()
    {
        std::cout << "bar::Drawing()\n";
    }

    void func3()
    {
        // Attempt 1
        //myFoo.func1(Drawing); // This won't work

        // Attempt 2
        myFoo.func2(this, &bar::Drawing); // Must pass an object instance if you plan to use the member function
    }
};

int main(int argc, char *argv[])
{
    bar b;

    return 0;
}

样本输出

func2: bar::Drawing()

【讨论】:

    猜你喜欢
    • 2013-12-26
    • 1970-01-01
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多