Calling C++ Member Functions Via a Function Pointer

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

C++ How to make function pointer to class method [duplicate]

A member function is quite a bit different from an ordinary function, so when you want to point to a member function you need a pointer-to-member-function, not a mere pointer-to-function. The syntax for a pointer-to-member-function includes the class that the member function is a member of:

void (Game::*mptr)();

This defines a pointer-to-member-function named mptr that holds a pointer to a member function of the class Games that takes no arguments and returns nothing. Contrast that with an ordinary function pointer:

void (*ptr)();

This defined a pointer-to-function named ptr that holds a pointer to a function that takes no arguments and returns nothing.

How to use function pointers to access member functions?

Lets look at this simple example,

struct Greeting {
void SayHello() { std::cout << "Hello!\n"; }

void (Greeting::*pfHello)() = nullptr;
};

int main()
{
Greeting g;

// Lets assign the function pointer to the pfHello variable.
g.pfHello = &Greeting::SayHello;

// Now lets call it like a traditional function pointer.
g.pfHello(); // Triggers an error!

// Now lets call it by dereferencing it.
(*g.pfHello)(); // Still triggers an error..

// Okay lets call it just like g.SayHello() but by swapping the dereferenced pointer with SayHello.
(g.*(g.pfHello))(); // Works fine!
}

By looking at the example, we can see that the only way to call the member function pointer is by providing the dereferenced function pointer as the function body (in this case SayHello). And the object needs to be instantiated in order to do this, just like how we would do it if were going to call the SayHello() method directly.

Why do we need to instantiate the object before calling it?

That's because in order for the function to access other member variables and member functions, the object needs to be instantiated. This wont be an issue for static functions (because they cant access member variables and member functions).

Why dereferenced function pointer?

Well that's because your not directly storing the function pointer. Your storing the address of the function pointer (g.pfHello = &Greeting::SayHello;). This is why we need to dereference it.

That's why we have to use this: (this->*(pfSort))(); instead of this: pfSort().

Hope this would clear some doubts!

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 can i call a member function pointer from another member function?

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

(this->*fnPointer)();

How to use function pointers to call member functions from its memory address?

One of your problems is at least that your code doesn't match your question. You talk about function pointers, yet you write void(NC_FontDevice::*_UseTexturesTransparency)(). That is not a function pointer. That is a pointer to member function (PMF). Entirely different beasts, and you can't assume these are simple pointers. They're generally not even the same size.

I suspect that you've found a function at 0x635FD0. That function probably looks like void _UseTexturesTransparency(NC_FontDevice*). Sure, it might have been (part of) a member function when it was compiled, but that doesn't really matter. This is hacking, we're being pragmatic here. Why deal with the complexities of a PMF if we can treat this as an ordinary function pointer?

[edit]
Per the comments, MSVC++ will have used ECX for the this argument in member functions; as it happens it also supports the __fastcall calling convention for regular functions which puts the first 32 bit argument in ECX. It's not a perfect replacement; __fastcall also uses EDX for its second argument. You might need a dummy argument there, if the existing code expects further arguments on the stack.

You can check for stack arguments because under the __thiscall calling convention for member functions, the callee cleans the stack. Luckily this matches the __fastcall convention.

C++: Calling member function via pointer

You need to tell the compiler which class the foos are coming from (otherwise it thinks they're functions from global scope):

void A::setPtr(int v){
if(v == 1){
_currentPtr = &A::foo1;
// ^^^^
} else {
_currentPtr = &A::foo2;
// ^^^^
}
}

and you need a set of parentheses here:

std::cout << (this->*_currentPtr)(4,5);
// ^ ^

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

You need an instance to call it:

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

Demo



Related Topics



Leave a reply



Submit