Calling C++ class methods via a function pointer

2018-12-31 14:19发布

How do I obtain a function pointer for a class member function, and later call that member function with a specific object? I’d like to write:

class Dog : Animal
{
    Dog ();
    void bark ();
}

…
Dog* pDog = new Dog ();
BarkFunction pBark = &Dog::bark;
(*pBark) (pDog);
…

Also, if possible, I’d like to invoke the constructor via a pointer as well:

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

Is this possible, and if so, what is the preferred way to do this?

9条回答
君临天下
2楼-- · 2018-12-31 15:07

Minimal runnable example

#include <cassert>

class C {
    public:
        int i;
        C(int i) : i(i) {}
        int m(int j) { return this->i + j; }
};

int main() {
    // Get a method pointer.
    int (C::*p)(int) = &C::m;

    // Create a test object.
    C c(1);
    C *cp = &c;

    // Operator .*
    assert((c.*p)(2) == 3);

    // Operator ->*
    assert((cp->*p)(2) == 3);
}

You cannot change the order of the parenthesis or omit them. The following do not work:

c.*p(2)
c.*(p)(2)

C++11 standard

.* and ->* are a singe operators introduced in C++ for this purpose, and not present in C.

C++11 N3337 standard draft:

  • 2.13 "Operators and punctuators" has a list of all operators, which contains .* and ->*.
  • 5.5 "Pointer-to-member operators" explains what they do
查看更多
孤独总比滥情好
3楼-- · 2018-12-31 15:11

A function pointer to a class member is a problem that is really suited to using boost::function. Small example:

#include <boost/function.hpp>
#include <iostream>

class Dog 
{
public:
   Dog (int i) : tmp(i) {}
   void bark ()
   {
      std::cout << "woof: " << tmp << std::endl;
   }
private:
   int tmp;
};



int main()
{
   Dog* pDog1 = new Dog (1);
   Dog* pDog2 = new Dog (2);

   //BarkFunction pBark = &Dog::bark;
   boost::function<void (Dog*)> f1 = &Dog::bark;

   f1(pDog1);
   f1(pDog2);
}
查看更多
路过你的时光
4楼-- · 2018-12-31 15:11

To create a new object you can either use placement new, as mentioned above, or have your class implement a clone() method that creates a copy of the object. You can then call this clone method using a member function pointer as explained above to create new instances of the object. The advantage of clone is that sometimes you may be working with a pointer to a base class where you don't know the type of the object. In this case a clone() method can be easier to use. Also, clone() will let you copy the state of the object if that is what you want.

查看更多
登录 后发表回答