【问题标题】:passing member function of one class to a member function of another class - segfault - mrmpi将一个类的成员函数传递给另一个类的成员函数 - segfault - mrmpi
【发布时间】:2016-12-03 23:41:40
【问题描述】:

编辑:

我尝试为此实现一个最少的代码并且它有效。我回到我的代码试图找出那里出了什么问题。这个问题从一开始就错了,留给以后用更正的最小代码参考(或者我应该删除它吗?)

#include <iostream>

class LibClass {
public:
        int mapLibClass( void (*callbackfunc) ( int, void*)) {
            std::cout << " in map " << std::endl;
            callbackfunc(8,NULL);
        }
};

class MyClass {
public:
        LibClass* objLibClass;

        MyClass(LibClass* objLibClass) : objLibClass(objLibClass) { }

        void runLibClass() {
            std::cout << "in runLibClass" << std::endl;
            objLibClass -> mapLibClass(&MyClass::callbackfunc);
        }
        static void callbackfunc(int i, void* ptr) {
            std::cout << "in callback" << std::endl;
        }
};

int main() {
        LibClass* libClassObj = new LibClass();
        MyClass myClassObj(libClassObj);
        myClassObj.runLibClass();
        return 0;
}

我正在使用 mrmpi 库(不需要知道该库,因为问题在下面解释,但它是 MapReduce for C++ 的实现)。该库接受回调函数作为其成员函数的参数:

class LibClass {
public:
    int mapLibClass( void (*callbackfunc)(int, KV*, void*)) { }
};

现在我有自己的类,它有一个(指向)LibClass 类型的成员变量,需要调用这个变量的 mapLibClass 函数,将我的类的函数传递给它。

class MyClass {
public:
    LibClass* objLibClass;

    MyClass(LibClass objLibClass) : objLibClass(objLibClass) { }

    void runLibClass() {
        //I have some extra lines here checking to make sure other member variables and also objLibClass are set correctly
        objLibClass -> mapLibClass(&MyClass::callbackfunc);
    }

    static void callbackfunc(int i, KV* kv, void* ptr) {
        //just an std::cout here to make sure I get into this function
    }
};

int main() {
    LibClass* libClassObj = new LibClass();
    MyClass myClassObj(libClassObj);
    myClassObj.runLibClass();
    return 0;
}

在从 runLibClass 函数内部调用 mapLibClass 之前,一切都很顺利。 mapLibClass 应该做一些事情,然后调用它作为参数接受的回调函数。但是当我运行我的程序时,它永远不会进入回调函数,而是出现分段错误。

如果我将 callbackfunc 设为非成员函数,程序运行正常,因此它与传入成员函数有关。我已经阅读了文档和其他 SO 帖子,但我所看到的只是我的成员 callbackfunc 应该是静态的(它是静态的,或者它甚至不会编译),或者我应该使用 boost::bind 和 boost::function (这需要我更改库源代码)。我无法弄清楚是什么导致了段错误。任何帮助都非常感谢,因为我在这方面花了太多时间。谢谢。

【问题讨论】:

  • 不编译无法复现ideone.com/trITGM
  • 非成员函数和静态成员函数没有区别。修复明显错误后,您的示例 works。请发帖minimal reproducible example
  • 很抱歉。在第一条评论之后,我开始编写最小代码:ideone.com/70THz8 ...并且...它现在运行。我想我应该在其他地方寻找问题。

标签: c++ mapreduce parameter-passing


【解决方案1】:

在传递成员函数作为参数之间,你需要有不同的声明。 下面有一个小例子,可能会对你有所帮助。

#include <iostream>
using namespace std;

class A {
public:
  void xx() { cout << "xx" << endl; }
};

void f(A &a, void (A::*x)()) {
  (a.*x)();
  cout << "calling A xx" << endl;
}

int main() {
  // your code goes here
  A a;
  f(a, &A::xx);
  return 0;
}

【讨论】:

  • "在传递成员函数作为参数之间,您需要有不同的声明。"呃……什么?
  • 我更改了代码以使其在未编译时运行(由 Stargateur 指出)。并意识到它有效,所以问题应该出在其他地方。对于那个很抱歉。 ideone.com/70THz8
【解决方案2】:

看起来你的ctor应该接收一个指针而不是值的类。 这就是你得到段错误的原因,因为你的指针是空的。
以下更改将解决您的问题:

MyClass(LibClass * objLibClass) : objLibClass(objLibClass) {}

【讨论】:

  • 不可能是这个,MyClass(LibClass objLibClass) : objLibClass(objLibClass) {}不要编译。
  • 编译器会尖叫(可能没有演员表,如果有的话也不会将指针设为空),这可能只是试图创建 mvce 的操作的错字。
  • 我更改了代码以使其在未编译时运行(由 Stargateur 指出)。并意识到它有效,所以问题应该出在其他地方。对于那个很抱歉。 ideone.com/70THz8
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 2022-01-10
相关资源
最近更新 更多