为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C++
富国沪深 2019-07-03 16:09:32
通过函数指针调用C+类方法如何获得类成员函数的函数指针,然后使用特定对象调用该成员函数?我想写:class Dog : Animal{     Dog ();     void bark ();}…Dog* pDog = new Dog ();BarkFunction pBark = &Dog::bark;(*pBark) (pDog);…此外,如果可能的话,我还想通过指针调用构造函数:NewAnimalFunction pNew = &Dog::Dog;Animal* pAnimal = (*pNew)();这是可能的吗?如果可能的话,最好的方法是什么?
查看完整描述

3 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

朗读,阅读这,这个详情:

// 1 define a function pointer and initialize to NULLint (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;
// C++class TMyClass{public:
   int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
   int DoMore(float a, char b, char c) const
         { cout << "TMyClass::DoMore" << endl; return a-b+c; };

   /* more of TMyClass */};pt2ConstMember = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore
   // Calling Function using Function Pointer(*this.*pt2ConstMember)(12, 'a', 'b');


查看完整回答
反对 回复 2019-07-03
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

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

最简单的方法是从typedef..对于成员函数,可以在类型声明中添加类名:

typedef void(Dog::*BarkFunction)(void);

然后,要调用该方法,请使用->*操作员:

(pDog->*pBark)();

此外,如果可能的话,我也希望通过指针调用构造函数。这是可能的吗?如果可能的话,最好的方法是什么?

我不相信你能和这样的构造器一起工作-函数和函数是特别的。实现这类任务的正常方法是使用工厂方法,它基本上只是一个静态函数,它为您调用构造函数。有关示例,请参阅下面的代码。

我已经修改了你的代码来做你所描述的。下面有一些警告。

#include <iostream>class Animal{public:

    typedef Animal*(*NewAnimalFunction)(void);

    virtual void makeNoise()
    {
        std::cout << "M00f!" << std::endl;
    }};class Dog : public Animal{public:

    typedef void(Dog::*BarkFunction)(void);

    typedef Dog*(*NewDogFunction)(void);

    Dog () {}

    static Dog* newDog()
    {
        return new Dog;
    }

    virtual void makeNoise ()
    {
        std::cout << "Woof!" << std::endl;
    }};int main(int argc, char* argv[]){
    // Call member function via method pointer
    Dog* pDog = new Dog ();
    Dog::BarkFunction pBark = &Dog::makeNoise;

    (pDog->*pBark)();

    // Construct instance via factory method
    Dog::NewDogFunction pNew = &Dog::newDog;

    Animal* pAnimal = (*pNew)();

    pAnimal->makeNoise();

    return 0;}

现在,尽管您通常可以使用Dog*代替Animal*由于多态的魔力,函数指针的类型遵循类层次结构的查找规则。因此,动物方法指针与Dog方法指针不兼容,换句话说,您不能分配Dog* (*)()类型变量Animal* (*)().

静电newDog方法是一个工厂的简单示例,它简单地创建并返回新实例。作为一个静态函数,它有一个正则函数。typedef(没有类限定符)。

在回答了上述问题后,我想知道是否没有更好的方法来达到你所需要的。有一些特定的场景,您可以这样做,但您可能会发现,还有其他模式更适合您的问题。如果你用更笼统的语言来描述你想要达到的目标,蜂巢思维可能会更有用!

与上述相关,您无疑会发现升压绑定库和其他相关模块非常有用。


查看完整回答
反对 回复 2019-07-03
?
12345678_0001

TA贡献1802条经验 获得超5个赞

我想没有人在这里解释过,有一个问题是你需要“成员指针“而不是普通函数指针。

函数的成员指针不仅仅是函数指针。在实现方面,编译器不能使用简单的函数地址,因为通常,只有知道要取消引用的对象(比如虚拟函数),才知道要调用的地址。您还需要知道对象,以便提供this当然是隐式参数。

说过你需要它们,现在我要说你真的需要避免它们。说真的,会员指点是一种痛苦。查看实现相同目标的面向对象的设计模式,或者使用boost::function或者上面提到的任何事情-假设你可以做出这个选择,也就是说。

如果要向现有代码提供函数指针,那么您真的需要作为一个简单的函数指针,您应该将一个函数作为类的静态成员来编写。静态成员函数不理解this,因此需要将对象作为显式参数传入。曾经有一个不寻常的习语,用于处理需要函数指针的旧C代码。

class myclass{
  public:
    virtual void myrealmethod () = 0;

    static void myfunction (myclass *p);}void myclass::myfunction (myclass *p){
  p->myrealmethod ();}

myfunction实际上只是一个普通函数(范围问题除外),函数指针可以用普通的C方式找到。

编辑-这种方法称为“类方法”或“静态成员函数”。与非成员函数的主要区别在于,如果从类外部引用它,则必须使用::范围解析算子例如,要获取函数指针,请使用&myclass::myfunction把它叫做“使用”myclass::myfunction (arg);.

这种情况在使用旧的Win 32 API时相当常见,这些API最初是为C而不是C+设计的。当然,在这种情况下,参数通常是LPARAM或类似的,而不是指针,并且需要进行一些转换。


查看完整回答
反对 回复 2019-07-03
  • 3 回答
  • 0 关注
  • 516 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信