【问题标题】:Assign pointer to class function to pointer to function [duplicate]将指向类函数的指针分配给指向函数的指针[重复]
【发布时间】:2016-01-22 14:22:24
【问题描述】:

我正在尝试将指向类函数的指针作为变量发送到另一个类。我试图将这两个类分开,这样我就可以重复使用代码,而无需在将来对其进行编辑。

我在 Windows 7 上使用 Visual Studio 2015 进行编译。

DATASTRUCT dataItem = {0, 1, 0, 1, dataText, parentClass::doSomething};

childClass.addItem(dataItem); //childClass is initiated as a member of parentClass

其他地方:

typedef struct dataStruct{
    double min_x;
    double max_x;
    double min_y;
    double max_y;
    GLTEXT label; //custom struct for text information
    void(*function)(void);
}DATASTRUCT;

我希望 childClass 能够执行其业务并检查某些参数,并且当 childClass 完成后,我希望它从 parentClass 调用 doSomething,而实际上并不知道它是一个嵌套类。

我在编译过程中得到的错误是:

void(parentClass::)() 不能用于初始化 void()() 的实体。

我可以定义一个标准函数并调用它,但这并不是每个 parentClass 所独有的,然后我必须指定我所指的 parentClass::doSomething。

我找到的最简单的解决方案是将childClass中指向函数的指针重新定义为void(parentClass::*)(),这正是我想要的,但不是如何我想要。

话虽如此,我不知道该去哪里,还有其他方法吗?类似的东西?

编辑:

如果可能,我将如何显式发送我的 childClass 所需的信息以正确动态地解释函数指针。

所以...

childClass.addItem(classInformation, dataItem, &parentClass::doSomething);

或者接收端总是必须提前知道“parentClass::”?那么现在是使用 void 指针的好时机吗?

我是在追自己的尾巴还是要去某个地方?

编辑:

这样的事情看起来很危险,但是,就是这样。

childClass.addItem(classInformation, dataItem, static_cast<void*>(&parentClass::doSomething));

childClass::callParent(classInformation, void*function){
    static_cast<classInformation.something*>(function)();
}

在这种情况下,“classInformation.something”会是什么?

【问题讨论】:

  • 成员函数需要一个他们可以操作的对象。在您的案例中,您将如何指定要访问哪一个?
  • 顺便说一句,你真的应该使用&amp;parentClass::doSomething。只有 MSVC 会原谅你错过了&amp;,这只是因为他们试图与 VC++6 兼容。
  • @MSalters 我会记住这一点,我曾经在 c 中的函数指针之前添加 &,但我开始在 c++ 中遇到类似指针的奇怪错误。到目前为止,我注意到 Visual Studio 似乎更喜欢没有。

标签: c++ function-pointers


【解决方案1】:

函数指针确实有限制。我建议改用std::function&lt;void()&gt;。请注意,您仍然必须知道将操作哪个对象成员函数。您可以使用std::bind 或 lambda 来执行此操作:

DATASTRUCT dataItem = 
    {0, 1, 0, 1, dataText, std::bind(&parentClass::doSomething, std::ref(someParentClassObject))};
//or
DATASTRUCT dataItem = 
    {0, 1, 0, 1, dataText, [&someParentClassObject](){ someParentClassObject.doSomething(); }};

【讨论】:

  • 以前从未听说过,看起来很困惑,但我终于有时间在电脑前尝试了,使用 std::function/bind 没有问题。更不用说这对函数调用没有影响,保留我想要的格式。你是一头野兽。去度过美好的一天吧。
【解决方案2】:

问题是类成员函数需要知道类变量在哪里,它无法知道它是否只需要一个指向类函数的函数指针,而没有对它所属的对象的引用成员。所以 parentClass::* 隐含地有一个指向对象的指针,而函数指针没有。

基本上,您需要跟踪对象才能调用其成员函数之一。您可以使用指向对象的指针并从中调用成员函数,也可以使用 parentClass::*,它在后台执行几乎相同的操作。

也许有一个更基本的潜在问题可以让您绕过这个限制。例如,与其问你是否能做到这一点,不如用另一种方法来完成你想要做的任何事情。

【讨论】:

  • 如果你使用指向函数的类指针指向一个函数,为什么 parentClass 需要知道变量在哪里?这不是函数本身就知道在一个设定的内存位置开始的东西吗?
  • 成员函数本身位于内存位置,但它不知道它属于哪个类的实例,而无需编译器传递指针。成员函数被编译和链接,然后它的一个副本位于内存中的某个位置。程序不会在每次创建新对象时创建该代码的新副本——这意味着为该类的所有实例调用相同的代码,因此代码不知道哪个实例正在调用它,除非它得到传递了一个指针。编译器将指针隐式传递给它。但是一个简单的函数指针不会。
  • 好的,这样解释对我来说更有意义。我想问题应该是如何将指针传递给明确指定哪个类实例而不具体指定类类型的类函数..?我现在只是让自己感到困惑。
猜你喜欢
  • 2015-11-25
  • 2013-01-16
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 2011-04-02
  • 1970-01-01
相关资源
最近更新 更多