猿问

通过函数指针调用C+类方法

通过函数指针调用C+类方法

如何获得类成员函数的函数指针,然后使用特定对象调用该成员函数?我想写:

class Dog : Animal{
    Dog ();
    void bark ();}…Dog* pDog = new Dog ();BarkFunction pBark = &Dog::bark;(*pBark) (pDog);…

此外,如果可能的话,我还想通过指针调用构造函数:

NewAnimalFunction pNew = &Dog::Dog;Animal* pAnimal = (*pNew)();

这是可能的吗?如果可能的话,最好的方法是什么?


富国沪深
浏览 517回答 3
3回答

一只名叫tom的猫

朗读,阅读这,这个详情://&nbsp;1&nbsp;define&nbsp;a&nbsp;function&nbsp;pointer&nbsp;and&nbsp;initialize&nbsp;to&nbsp;NULLint&nbsp;(TMyClass::*pt2ConstMember)(float,&nbsp;char,&nbsp;char)&nbsp;const&nbsp;=&nbsp;NULL; //&nbsp;C++class&nbsp;TMyClass{public: &nbsp;&nbsp;&nbsp;int&nbsp;DoIt(float&nbsp;a,&nbsp;char&nbsp;b,&nbsp;char&nbsp;c){&nbsp;cout&nbsp;<<&nbsp;"TMyClass::DoIt"<<&nbsp;endl;&nbsp;return&nbsp;a+b+c;}; &nbsp;&nbsp;&nbsp;int&nbsp;DoMore(float&nbsp;a,&nbsp;char&nbsp;b,&nbsp;char&nbsp;c)&nbsp;const &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;cout&nbsp;<<&nbsp;"TMyClass::DoMore"&nbsp;<<&nbsp;endl;&nbsp;return&nbsp;a-b+c;&nbsp;}; &nbsp;&nbsp;&nbsp;/*&nbsp;more&nbsp;of&nbsp;TMyClass&nbsp;*/};pt2ConstMember&nbsp;=&nbsp;&TMyClass::DoIt;&nbsp;//&nbsp;note:&nbsp;<pt2Member>&nbsp;may&nbsp;also&nbsp;legally&nbsp;point&nbsp;to&nbsp;&DoMore &nbsp;&nbsp;&nbsp;//&nbsp;Calling&nbsp;Function&nbsp;using&nbsp;Function&nbsp;Pointer(*this.*pt2ConstMember)(12,&nbsp;'a',&nbsp;'b');

翻过高山走不出你

如何获得类成员函数的函数指针,然后使用特定对象调用该成员函数?最简单的方法是从typedef..对于成员函数,可以在类型声明中添加类名:typedef&nbsp;void(Dog::*BarkFunction)(void);然后,要调用该方法,请使用->*操作员:(pDog->*pBark)();此外,如果可能的话,我也希望通过指针调用构造函数。这是可能的吗?如果可能的话,最好的方法是什么?我不相信你能和这样的构造器一起工作-函数和函数是特别的。实现这类任务的正常方法是使用工厂方法,它基本上只是一个静态函数,它为您调用构造函数。有关示例,请参阅下面的代码。我已经修改了你的代码来做你所描述的。下面有一些警告。#include&nbsp;<iostream>class&nbsp;Animal{public: &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Animal*(*NewAnimalFunction)(void); &nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;makeNoise() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;"M00f!"&nbsp;<<&nbsp;std::endl; &nbsp;&nbsp;&nbsp;&nbsp;}};class&nbsp;Dog&nbsp;:&nbsp;public&nbsp;Animal{public: &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;void(Dog::*BarkFunction)(void); &nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;Dog*(*NewDogFunction)(void); &nbsp;&nbsp;&nbsp;&nbsp;Dog&nbsp;()&nbsp;{} &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;Dog*&nbsp;newDog() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;Dog; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;makeNoise&nbsp;() &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;<<&nbsp;"Woof!"&nbsp;<<&nbsp;std::endl; &nbsp;&nbsp;&nbsp;&nbsp;}};int&nbsp;main(int&nbsp;argc,&nbsp;char*&nbsp;argv[]){ &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Call&nbsp;member&nbsp;function&nbsp;via&nbsp;method&nbsp;pointer &nbsp;&nbsp;&nbsp;&nbsp;Dog*&nbsp;pDog&nbsp;=&nbsp;new&nbsp;Dog&nbsp;(); &nbsp;&nbsp;&nbsp;&nbsp;Dog::BarkFunction&nbsp;pBark&nbsp;=&nbsp;&Dog::makeNoise; &nbsp;&nbsp;&nbsp;&nbsp;(pDog->*pBark)(); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Construct&nbsp;instance&nbsp;via&nbsp;factory&nbsp;method &nbsp;&nbsp;&nbsp;&nbsp;Dog::NewDogFunction&nbsp;pNew&nbsp;=&nbsp;&Dog::newDog; &nbsp;&nbsp;&nbsp;&nbsp;Animal*&nbsp;pAnimal&nbsp;=&nbsp;(*pNew)(); &nbsp;&nbsp;&nbsp;&nbsp;pAnimal->makeNoise(); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}现在,尽管您通常可以使用Dog*代替Animal*由于多态的魔力,函数指针的类型不遵循类层次结构的查找规则。因此,动物方法指针与Dog方法指针不兼容,换句话说,您不能分配Dog* (*)()类型变量Animal* (*)().静电newDog方法是一个工厂的简单示例,它简单地创建并返回新实例。作为一个静态函数,它有一个正则函数。typedef(没有类限定符)。在回答了上述问题后,我想知道是否没有更好的方法来达到你所需要的。有一些特定的场景,您可以这样做,但您可能会发现,还有其他模式更适合您的问题。如果你用更笼统的语言来描述你想要达到的目标,蜂巢思维可能会更有用!与上述相关,您无疑会发现升压绑定库和其他相关模块非常有用。

12345678_0001

我想没有人在这里解释过,有一个问题是你需要“成员指针“而不是普通函数指针。函数的成员指针不仅仅是函数指针。在实现方面,编译器不能使用简单的函数地址,因为通常,只有知道要取消引用的对象(比如虚拟函数),才知道要调用的地址。您还需要知道对象,以便提供this当然是隐式参数。说过你需要它们,现在我要说你真的需要避免它们。说真的,会员指点是一种痛苦。查看实现相同目标的面向对象的设计模式,或者使用boost::function或者上面提到的任何事情-假设你可以做出这个选择,也就是说。如果要向现有代码提供函数指针,那么您真的需要作为一个简单的函数指针,您应该将一个函数作为类的静态成员来编写。静态成员函数不理解this,因此需要将对象作为显式参数传入。曾经有一个不寻常的习语,用于处理需要函数指针的旧C代码。class&nbsp;myclass{ &nbsp;&nbsp;public: &nbsp;&nbsp;&nbsp;&nbsp;virtual&nbsp;void&nbsp;myrealmethod&nbsp;()&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;static&nbsp;void&nbsp;myfunction&nbsp;(myclass&nbsp;*p);}void&nbsp;myclass::myfunction&nbsp;(myclass&nbsp;*p){ &nbsp;&nbsp;p->myrealmethod&nbsp;();}自myfunction实际上只是一个普通函数(范围问题除外),函数指针可以用普通的C方式找到。编辑-这种方法称为“类方法”或“静态成员函数”。与非成员函数的主要区别在于,如果从类外部引用它,则必须使用::范围解析算子例如,要获取函数指针,请使用&myclass::myfunction把它叫做“使用”myclass::myfunction (arg);.这种情况在使用旧的Win 32 API时相当常见,这些API最初是为C而不是C+设计的。当然,在这种情况下,参数通常是LPARAM或类似的,而不是指针,并且需要进行一些转换。
随时随地看视频慕课网APP
我要回答