【问题标题】:How to call a C++ class method, which is given as a parameter?如何调用作为参数给出的 C++ 类方法?
【发布时间】:2018-09-11 01:26:01
【问题描述】:

我正在尝试将一个方法作为参数传递给其他方法。

Magner.h:

Class Manager{
public:
 timeCount(void (Manger::*function)(void));
void passedFuction();
}

Manager.cpp,我正在尝试通过

致电timeCount
timeCount(&Manager::passedFuction());

TimeCount 正文:

void Manager::timeCount(void(Manager::*function)(void))
{
    std::cout << "It works";
    (*function)(); // here is error
}

ViusalStudio 说:

void*Manager::*function)() '*' 的操作数必须是指针

我应该如何纠正它? 我学习的例子是:http://www.cplusplus.com/forum/beginner/6596/

【问题讨论】:

  • 您正在学习的示例早于 C++11。这不是我在 Modern C++ 中使用的方式——我会使用 std::function 和 lambdas。此外,您没有按照示例演示的方式进行操作。

标签: c++ pointers methods parameters pointer-to-member


【解决方案1】:

指向成员函数的指针 (pmf) 不是指针。让我重复一遍:

指向成员函数的指针不是指针。

要调用 pmf,您必须向它提供要调用它的对象。你可能想要:

    (this->*function)();

如果你有另一个正确类型的对象obj,你也可以使用:

    (obj.*function)();

【讨论】:

  • 好的。刚试过,它的工作原理。 pmf 是指参数功能吗?
  • 否,“指向成员函数的指针”。我将编辑帖子以澄清。
  • @anatolyg :我想是的,是的。 pmf 的大部分困难与误导性名称有关。
【解决方案2】:

void (Manger::*function)(void) 语法适用于Manager 类的成员函数,它不能与Manager之外的函数一起使用。

要解决这个缺点,请改为传递std::function&lt;void(void)&gt;,这样您就可以使用常规函数调用语法来调用自身:

void Manager::timeCount(std::function<void(void)> f) {
    std::cout << "It works";
    f();
}

这里是一个完整的演示如何使用成员和非成员函数调用timeCount

struct Manager {
    string name;
    void timeCount(std::function<void(void)> f) {
        std::cout << "This is " << name << " manager" << endl;
        f();
    }
};

void foo() {
    cout << "I'm foo" << endl;
}

struct Test {
    int x;
    void bar() {
        cout << "I'm bar " << x << endl;
    }
};

int main() {
    Manager mgr {"time"};
    mgr.timeCount(foo);
    Test tst = {234};
    mgr.timeCount(std::bind( &Test::bar, tst));
    return 0;
}

Demo.

【讨论】:

  • 在这种情况下你会怎么称呼timeCount
  • @MartinBonner 我添加了一个运行演示,请看一下。
【解决方案3】:

从 c++17 开始,我们有 std::invoke:

std::invoke(function, this);

std::invoke(function, *this);

都可以。最小演示:

#include <functional>
#include <iostream>
class Manager
{
public:
    void timeCount(void (Manager::*function)(void));
    void passedFuction()
    {
        std::cout << "call passedFunction\n";
    }
};

void Manager::timeCount(void (Manager::*function)(void))
{
    std::cout << "It works\n";
    std::invoke(function, *this);
    //    (*function)(); // here is error
}

int main()
{
    Manager a;
    a.timeCount(&Manager::passedFuction);
}

有效

调用传递函数

live demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 2010-12-21
    • 2018-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-05
    相关资源
    最近更新 更多