I want to get the function pointer of a member function of the current instance of a C++ class. Then I want to add that function pointer to a global registry.
I can't create the instance in a separate location and add the function pointer there. It should get added within this instance.
This is what I have done. But it doesn't work as intended. Is there anything I am doing wrong here?
Example
In MyClass.h
class MyClass
{
public:
MyClass();
~MyClass();
typedef int (MyClass::*fpointer)(int);
int foo(int val);
private:
void addFuncPointer();
}
In MyClass.cpp
MyClass::MyClass()
{
addFuncPointer();
}
int MyClass::foo(int val)
{
// Function Definition
}
void MyClass::addFuncPointer()
{
fpointer funct = &MyClass::foo;
//I am adding this function pointer to a global registry.
GlobalRegistry.add(globalindex, funct);
globalindex++;
}
In Main.cpp
int main()
{
MyClass* cls = new MyClass();
GlobalRegistry.getFunctionPointer(validindex)->call();
return 0;
}
The problem that you are experiencing is caused by the fact that all objects of a class share the same code for their member functions. So if you want to invoke a member function for a particular instance, you're gonna need to save both, a pointer to the instance and a pointer to the member function.
Since C++11 this can be wrapped into a function object:
struct Foo {
void func() { /* ... */ }
} foo;
auto mem_func = std::bind(&Foo::func, &foo);
mem_func();
Related
This question already has answers here:
Calling C++ member functions via a function pointer
(10 answers)
Closed 9 months ago.
I'm having trouble making a function pointer to a class method. I made a function pointer to a non-class method and it works fine.
int foo(){
return 5;
}
int main()
{
int (*pointer)() = foo;
std::cout << pointer();
return 0;
}
I tried to apply this to have an instance variable in a class be a function pointer.
This is the header file. It declares the private method Print which the variable method will point to.
class Game
{
public:
Game();
private:
void Print();
void (method)( void );
};
The Game constructor attempts to assign the pointer method to the address of the Print method. Upon compile, an error comes up at that line saying "error: reference to non-static member function must be called;". I don't know what that means. Whats the correct way of implementing this?
Game::Game( void )
{
method = &Game::Print;
}
void Game::Print(){
std::cout << "PRINT";
}
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.
Just found out you can do
#include <functional>
#include <cassert>
using namespace std;
struct Foo {
int x;
int foo() { return x; }
};
int main() {
function<int(Foo&)> f = &Foo::foo;
Foo foo = { 3 };
assert(f(foo) == 3);
foo.x = 5;
assert(f(foo) == 5);
}
std::mem_fn() might work too: https://en.cppreference.com/w/cpp/utility/functional/mem_fn
1- Use the following syntax to point to a member function:
return_type (class_name::*ptr_name) (argument_type) = &class_name::function_name;
2- keep in mind to have a pointer to member function you need to make it public.
in your case:
class Game
{
public:
Game(){}
void print() {
//todo ...
}
};
// Declaration and assignment
void (Game::*method_ptr) () = &Game::print;
I tried to use std::shared_pointer with deleter. I tried to use a member function as the deleter. However it could not compiled. Compiler gave me a error message but I could not understand why it did not work. Does someone knows why it did not work? Thank you very much.
Simplified code is following,
#include <memory>
class MemberFunctionPointerInConstructor {
public:
MemberFunctionPointerInConstructor(void) {
std::shared_ptr<int> a = std::shared_ptr<int>(new int(1), deleter); // this line makes a compiler error message
}
void deleter(int* value) {
delete value;
}
};
The error message from compiler is following,
error: invalid use of non-static member function
std::shared_ptr<int> a = std::shared_ptr<int>(new int(1), deleter);
^
Thank you very much.
To use a member function that isn't bound to an instance of your class you'd have to declare the method static
static void deleter(int* value) {
delete value;
}
If you want to use a non-static member function as a deleter, you have to bind it to an instance—but note that the instance would need to still be alive when the deleter is invoked. For example,
class ShorterName {
public:
ShorterName(void) {
using namespace std::placeholders;
auto a = std::shared_ptr<int>(new int(1),
std::bind(&A::deleter, this, _1));
}
void deleter(int* value) {
delete value;
}
};
If you don't need a particular instance, you can make the function static, so it doesn't require an instance.
class ShorterName {
public:
ShorterName(void) {
auto a = std::shared_ptr<int>(new int(1), deleter);
}
static void deleter(int* value) {
delete value;
}
};
There are several ways to solve this. If you actually mean a non-static member function, one way of doing so (not the only one) would be through a lambda function:
class MemberFunctionPointerInConstructor {
public:
MemberFunctionPointerInConstructor() {
std::shared_ptr<int> a = std::shared_ptr<int>(
new int(1),
[this](int *p){this->deleter(p);});
}
void deleter(int* value) {
delete value;
}
};
The answer is very simple.
static void deleter(int* value) {
delete value;
}
You must make the function static, because otherwise it might use member variables of that class, which can be only done if there is an instance for it to be done with, and here that is not the case.
I'm new to C++ and I need a class member function to call itself from its own definition, like this -
class MyClass {
public: // or private: ?
// Some code here
// ...
void myfunction();
// ...
};
void MyClass::myfunction()
{
// Some code here
// ...
// Call MyClass::myfunction() here, but how?
// ...
}
but I don't know the proper syntax for it and how can it be called by itself without creating an object usually done like this - object_name.member_function(), if possible?
And, will there be any difference if myfunction() belongs to public: or private:?
Since the function isn't static, you already do have an instance to operate on
void MyClass::myfunction()
{
// Some code here
// ...
this->myfunction();
// ...
}
You could leave the this-> off, I was just being more clear about how the function is able to be called.
myfunction() is in the scope of the class, so you can "simply" call it:
class MyClass {
public:
// Some code here
// ...
void myfunction();
// ...
};
void MyClass::myfunction()
{
myfunction();
}
Note, however, that this will give a stack overflow. You need a means to stop the recursion.
Member functions are actually a form of syntactic sugar. They describe a function that somehow secretly takes a pointer to an object instance which, inside the function, is accessible as this.
struct Foo {
vod bar();
};
Foo foo;
foo.bar();
What you're really doing in the call here is calling a Foo::bar(&foo); and bar is really taking a pointer Foo* this. How that's done varies from implementation to implementation, some compilers/architectures will use a special register to track the current object.
An additional piece of syntactic sugar makes all member variables and functions visible to you within a member function as though they are locally scoped
struct Foo {
int i;
int add(int n) {
return i + n;
}
int addx2(int n) {
return add(n) * 2;
}
};
What's actually happening here is:
return this->i + n;
and
return this->add(n) * 2;
This means its very easy to run into situations where you have conflicts between local and member names.
struct Foo {
int i;
Foo(int i) {
i = i; // not what you expected
}
};
For this reason, many engineers make careful use of case or prefixes or suffixes to help them distinguish members, parameters and variables.
struct Foo { // Uppercase for types and functions
int m_i; // m_ for member
Foo(int i_, int j_) {
int i = sqrt(i));
m_i = i + j_;
}
int Add(int i) {
return i_ + i;
}
};
There are various different patterns people use - some people use _name to denote a member, some use name_ and fn_ to denote members.
struct Foo {
int i_;
int add_(int _i) {
return i_ + _i;
}
};
The main thing is to be consistent.
but I don't know the proper syntax for it and how can it be called by itself without creating an object usually done like this - object_name.member_function(), if possible?
Use:
void MyClass::myfunction()
{
// Some code here
// ...
// Call MyClass::myfunction() here, but how?
// One way to call the function again.
this->myfunction();
// ...
}
this->mufunction() can be replaced by myfunction(). Use of this is a stylistic option that makes the code easier to read for some, like me.
And, will there be any difference if myfunction() belongs to public: or private:?
No, there won't be. You can call any member function of the class from another member function.
I am having a vector of function pointers in one class and to it i want to pass address of function in some other class. The following implementation gives errors. What is the correct way?
class A
{
public:
void func ()
{
}
};
class B
{
public:
std::vector<void(*)()) myVec;
void update_func()
{
myVec.push_back(&A::func);
}
};
int main()
{
B* b = new B;
b->update_func();
return 0;
}
A pointer to the non-static member function A::func doesn't have type void(*)(void), it has type void(A::*)(void). So either change the vector to match the elements that you want it to have, or else use a pointer to a function of the correct type for the vector.
A's func() has to be static to match the declaration of the function pointer. Meanwhile, it needs to be public such that it is accessible to class B.
update_func() in B also needs to be public since otherwise in main it is not accessible.
vector declaration has typo, it has to be vector<>, not vector<).
//
class A
{
public:
static void func ()
{
}
};
class B
{
std::vector<void(*)()> myVec;
public void update_func()
{
myVec.push_back(&A::func);
}
};
int main()
{
B* b = new B;
b->update_func();
return 0;
}
This code has many issues..
first b->func should have () after it if you want to call that function..
second.. what is void update func().. also bad code..
third you cannot use these functions since they are private...
you do however push it correctly into the vector...
I need to call a non static member function from a static member function of the same class.
The static function is a callback. It can receive only void as data, though which i pass a char*. So i cannot directly provide the class instance to the callback. I can pass a structure instead of char to the callback function. Can anyone give eg code to use the non static member function in a static member function . and use the structure in the static member function to use the instance of the class to call the non static member function?
Normally such a callback would look like this:
void Callback( void* data)
{
CMyClass *myClassInstance = static_cast<CMyClass *>(data);
myClassInstance->MyInstanceMethod();
}
Of course, you need to make sure, data points to an instance of your class. E.g.
CMyClass* data = new CMyClass();
FunctionCallingMyCallback( data, &Callback);
delete data;
Now, if I understand you correctly, you need to also pass a char*.
You can either wrap both in a struct and unwrap it in the callback like so:
MyStruct* data = new MyStruct();
data->PtrToMyClass = new CMyClass();
data->MyCharPtr = "test";
FunctionCallingMyCallback( data, &Callback);
delete data->PtrToMyClass;
delete data;
void Callback( void* data)
{
MyStruct *myStructInstance = static_cast<MyStruct *>(data);
CMyClass *myClassInstance = myStructInstance->PtrToMyClass;
char * myData = myStructInstance->MyCharPtr;
myClassInstance->MyInstanceMethod(myData);
}
or, if you can modify the definition of CMyClass, put all the necessary data in class members, so that you can use a callback as in the first example.
If your instance is a singleton (usually implemented using a private or protected constructor and a static pointer to itself) you can do e.g.:
class MyClass {
private:
MyClass():myInstance(0) {}
MyClass *myInstance;
void callback();
public:
~MyClass() {}
static MyClass *getInstance();
static void myCallback();
};
MyClass *MyClass::getInstance() {
if(!myInstance) {
myInstance = new MyClass;
}
return myInsance;
}
void MyClass::callback() {
// non-static callback
}
void MyClass::myCallback() {
getInstance()->callback();
}
If you don't use a singleton but you can pass the instance cast to a void * then you can do this instead:
void MyClass::myCallback(void *data) {
MyClass *instance = static_cast<MyClass *>(data);
instance->callback();
}
This is the only way :
#include <iostream>
#include <cassert>
struct A;
A *oneObj = NULL;
struct A
{
A(){
oneObj=this;
}
~A(){
oneObj=NULL;
}
void foo()
{
}
static void boo()
{
assert( NULL != oneObj );
oneObj->foo();
}
};
int main()
{
A onlyOne;
A::boo();
}
I need to call a non static member function from a static member
function of the same class. The static function is a callback. It can
receive only void as data, though which i pass a char*.
This shows that present design is flawed or inproper. IMHO, you should rather think of changing the design. Just imagine if you somehow get the things working but what about the maintainability an readability of the code.
I would suggest that you should change your callback function to different signature and made according changes.
class A {
//...
static void CallBack (A *pObj)
{
// logic
}
};