How to Call a Pointer-To-Member-Function

C++ Call Pointer To Member Function

Pointers to non-static member functions are a unique beast with unique calling syntax.

Calling those functions require you to supply not just named parameters, but also a this pointer, so you must have the Box pointer handy that will be used as this.

(box->*h)(xPos, yPos, width, height);

How to call through a member function pointer?

More parentheses are required:

(bigCat.*pcat)();
^ ^

The function call (()) has higher precedence than the pointer-to-member binding operator (.*). The unary operators have higher precedence than the binary operators.

Use pointer to member function to determine which function to call

Syntax to call a member function via member function pointer is

(this->*memf)();

You cannot magically turn the string into a member function pointer. Sloppy speaking, names of functions do not exist at runtime. If you want such mapping you need to provide it yourself. No way around that. What you can avoid is the "forest of if-else" by using a std::unordered_map:

#include <unordered_map>
#include <string>
#include <iostream>

class Karen
{
public:
void complain(std::string level) {
static const std::unordered_map<std::string, void(Karen::*)() const> m{
{"debug",&Karen::debug},
{"info",&Karen::info},
{"warning",&Karen::warning},
{"error",&Karen::error}
};
auto it = m.find(level);
if (it == m.end()) return;
(this->*(it->second))();
}

private:
void debug(void) const { std::cout << "debug\n"; }
void info(void) const { std::cout << "info\n"; }
void warning(void) const { std::cout << "warning\n"; }
void error(void) const { std::cout << "error\n"; }
};

int main() {
Karen k;
k.complain("info");
}

Live Demo

As mentioned in comments, you could use an enum in place of the string. When possible you should use the help of the compiler, which can diagnose a typo in an enum but not in a string. Alternatively you could directly pass a member function pointer to complain. Then implementation of complain would be trivial, no branching needed. Though this would require the methods to be public and the caller would have to deal with member function pointers.


If you are not allowed to use C++11 or newer you should have a serious talk with your teacher. Soon C++20 will be the de facto standard and things have changed quite a lot. I am not fluent in C++98 anymore, so here is just a quick fix of the above to get it working somehow. You cannot use std::unordered_map but there is std::map and initialization of the map is rather cumbersome:

#include <map>
#include <string>
#include <iostream>

class Karen
{
typedef void(Karen::*memf_t)() const;
typedef std::map<std::string,void(Karen::*)() const> map_t;

public:
void complain(std::string level) {
map_t::const_iterator it = get_map().find(level);
if (it == get_map().end()) return;
(this->*(it->second))();
}

private:
const map_t& get_map(){
static const map_t m = construct_map();
return m;
}
const map_t construct_map() {
map_t m;
m["debug"] = &Karen::debug;
m["info"] = &Karen::info;
m["warning"] = &Karen::warning;
m["error"] = &Karen::error;
return m;
}
void debug(void) const { std::cout << "debug\n"; }
void info(void) const { std::cout << "info\n"; }
void warning(void) const { std::cout << "warning\n"; }
void error(void) const { std::cout << "error\n"; }
};

int main() {
Karen k;
k.complain("info");
}

Live Demo

How do I call pointer-to-member functions from another class?

You need an instance to call it:

void Game::tick(){
(this->*(button1->click))();
}

Demo

How can i call a member function pointer from another member function?

You need to specify which object to call the function on:

(this->*fnPointer)();

Calling C++ member functions via a function pointer

Read this for detail :

// 1 define a function pointer and initialize to NULL

int (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');

Function pointer to member function

The syntax is wrong. A member pointer is a different type category from a ordinary pointer. The member pointer will have to be used together with an object of its class:

class A {
public:
int f();
int (A::*x)(); // <- declare by saying what class it is a pointer to
};

int A::f() {
return 1;
}

int main() {
A a;
a.x = &A::f; // use the :: syntax
printf("%d\n",(a.*(a.x))()); // use together with an object of its class
}

a.x does not yet say on what object the function is to be called on. It just says that you want to use the pointer stored in the object a. Prepending a another time as the left operand to the .* operator will tell the compiler on what object to call the function on.

How to switch with pointer to member functions?

Your member function pointer typedef is wrong (Despite the other issues in the shown code). You need

typedef void(A::*RunPtr)(int);

Or you can provide the alias for the member function pointer of class A with the help of using keyword as follows:

using RunPtr = void(A::*)(int);
RunPtr RunMethod;

Now in the SetOn you can do member pointer assignment as follows

void SetOn(bool value)
{
RunMethod = value ? &A::RunOn : &A::RunOff;
}

Now, in order to call the stored member function pointer, you may/ can provide a Run member function as follows:

void  Run(int arg)
{
std::invoke(RunMethod, this, arg);
// do something...
}

The call to member function is a bit tricky.
However, this can be done using more generic std::invoke from <functional> header (Since c++17).

Here is the complete example:

#include <iostream>
#include <functional> // std::invoke

class A
{
using RunPtr = void(A::*)(int);
// or with typedef
// typedef void(A::*RunPtr)(int);
RunPtr RunMethod;

public:
void SetOn(bool value)
{
RunMethod = value ? &A::RunOn : &A::RunOff;
}

void Run(int arg)
{
std::invoke(RunMethod, this, arg);
// do something...
}

void RunOn(int arg) { std::cout << "RunOn: " << arg << "\n"; }

void RunOff(int arg) { std::cout << "RunOff: " << arg << "\n"; }
};

int main()
{
A obj;
obj.SetOn(true);
obj.Run(1); // prints: RunOn: 1
obj.SetOn(false);
obj.Run(0); // prints: RunOff: 0
}

(See a Demo)

How to call through pointer-to-member function saved in a container?

Because of the priority binding for the () operator, you need to add some more parens:

result = (this->*(*iter))();


Related Topics



Leave a reply



Submit