简体   繁体   中英

Pointer to member function syntax

I'm trying to wrap my head around pointers to member functions and am stuck with this example:

#include <iostream>

class TestClass {
  public:
    void TestMethod(int, int) const;
};

void TestClass::TestMethod(int x, int y) const {
  std::cout << x << " + " << y << " = " << x + y << std::endl;
}

int main() {
  void (TestClass::*func)(int, int) const;
  func = TestClass::TestMethod;

  TestClass tc;
  tc.func(10, 20);

  return 0;
}

What I think the code should do:

  • In the first line of main I declare a pointer to a member function of class TestClass , which returns nothing/takes two int 's and is declared const , called func .
  • The second line assigns the member-function TestMethod (of class TestClass ) to func , which satisfies these criteria.
  • The forth line creates an TestClass -object called tc .
  • The fifth line tries to call the member function pointed to by func on the TestClass -object tc .

I get two compilation errors:

  • Instead of assigning TestClass::TestMethod to func . The compiler tries to call TestClass::TestMethod (even though it's not static , therefore throws an error):

     testPointerToMemberFunc.cpp:14:21: error: call to non-static member function without an object argument func = TestClass::TestMethod; ~~~~~~~~~~~^~~~~~~~~~ 
  • The compiler tries to call a function named func on tc , instead of the function, pointed to by func . To me this seems, like func isn't declared the right way (as a pointer to a member function):

     testPointerToMemberFunc.cpp:17:6: error: no member named 'func' in 'TestClass' tc.func(10, 20); ~~ ^ 

What am I doing wrong?

func = TestClass::TestMethod; should be func = &TestClass::TestMethod; , and tc.func(10, 20) should be (tc.*func)(10, 20) (in the latter, note that there are two changes: . becomes .* , and there are added parentheses; both are needed).

Simple syntax subtleties.

func = &TestClass::TestMethod;
//     ^ Missing ampersand to form a pointer-to-member

TestClass tc;
(tc.*func)(10, 20);
// ^^ Using the dot-star operator to dereference the pointer-to-member,
// while minding its awkward precedence with respect to the call operator.

Pointers to members (functions or otherwise), are very different than regular pointers, despite having some similarity in the syntax. The way that regular functions act like pointers to functions, and vice-versa, is inherited from C, but C doesn't support pointers to members, so it wasn't necessary for those to work that way in C++.

To make a pointer to member, you have to explicitly use & , and you have to explicitly use .* to indirect it, which is perhaps more what you might expect if you weren't used to the way functions work in C:

func = &TestClass::TestMethod;
(tc.*func)(10, 20);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM