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 twoint
's and is declaredconst
, called func. - The second line assigns the member-function
TestMethod
(of classTestClass
) tofunc
, 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 theTestClass
-objecttc
.
I get two compilation errors:
Instead of assigning
TestClass::TestMethod
tofunc
. The compiler tries to callTestClass::TestMethod
(even though it's notstatic
, 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
ontc
, instead of the function, pointed to byfunc
. To me this seems, likefunc
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?
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.
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).
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);
来源:https://stackoverflow.com/questions/39056740/pointer-to-member-function-syntax