I was wondering if a static member function essentially means that it gets an address in memory at compile-time and never changes it during the whole program.
Therefore it gives us the chance to pass it around in pointers without any fear as we are always sure that we will forever find it in the same place.
all functions have static addresses assigned to them at compile time (it's a little bit different for dynamically loaded libraries). Member function (static or not) is a standard function, it's address is known at compile time. How else linker could work?
Using static function u can call constructor which is declared as a private.
Here is code,
#include <iostream>
using namespace std;
class STATIC
{
private:
STATIC()
{
cout<<"In Constructor..."<<endl;
}
public:
static void fun()
{
STATIC a1;
}
};
int main()
{
STATIC::fun();
}
This is one of the use of Static member function.
A static member function is just a regular free function with a funny name. A pointer to a function is compatible with a pointer to a static member function.
A non-static member function is instead a function that receives and extra implicit hidden this parameter as first parameter.
However a pointer to a non-static member function is not compatible with a pointer to a function.
To call a non-static member function using a pointer to member function you need to provide an instance... and also the syntax is quite strange: (x.*member_ptr)(...) if x is an object reference, or (x->*member_ptr)(...) if x is a pointer.
A pointer to a non-static member function and a pointer to a function are incompatible types and there's no portable way to convert one in the other.
If you know the instance and you want to have a callable object to invoke one of its non-member function you can use (with C++11) an std::function wrapping a lambda.
#include <functional>
#include <string.h>
#include <iostream>
struct Foo {
int x;
Foo(int x) : x(x) {}
void bar() { std::cout << x << std::endl; }
static void baz() { std::cout << "Here\n"; }
};
int main(int argc, const char *argv[]) {
void (Foo::*f)() = &Foo::bar; // Non-static function member pointer
void (*g)() = &Foo::baz; // Static member function = function
Foo x(42);
(x.*f)(); // Prints 42
g(); // Prints "Here"
// Portable way to call a non-static member function just using ff()
std::function<void()> ff = [&x](){ x.bar(); };
ff(); // Prints 42 too
// Hack zone... just to show that on many compilers
// even a pointer to non-static member function is just
// a pointer to a function that accepts however `this`
// as an extra first parameter.
void (*hack)(void *);
memcpy(&hack, &f, sizeof(hack));
hack(&x); // Prints 42 too on g++/clang++ (NOT PORTABLE!!)
return 0;
}
Related
The XSetErrorHandler() function from X11 lib expects a function.
If I define a function above my main() [in main.cpp] like:
int catch_error(Display *disp, XErrorEvent *xe){return 0;}
Then I do the following:
XSetErrorHandler(catch_error);
It works.
How can I put the catch_error function in a class named WindowHandler and then pass it to XSetErrorHandler();
I tried the following:
WindowHandler window_handler = new WindowHandler();
XSetErrorHandler(WindowHandler::catch_error);
XSetErrorHandler(window_handler->catch_error);
XSetErrorHandler((*window_handler).catch_error);
Error for 1) argument of type "int (WindowHandler::*)(Display *disp, XErrorEvent *xe)" is incompatible with parameter of type "XErrorHandler"
Error for 2) and 3) A pointer to a bound function may only be used to call that fucntion
Thanks for your help!
The problem is that a non-static member function expects an implicit first argument, which is a pointer or a reference to the class (in this case WindowHandler). So the signature differs from the free catch_error function, if we take the implicit argument into account.
I don't know how XSetErrorHandler is declared, but the function might accept functors: In this case, you could wrap the call to WindowHandler::catch_error in a lambda expression that captures a pointer to your WindowHandler instance.
WindowHandler* window_handler = new WindowHandler();
XSetErrorHandler(
[window_handler](Display *disp, XErrorEvent *xe) {
return window_handler->catch_error(disp, xe);
}
);
delete window_handler; // if you really must use new (why would you ever?), please also delete.
Here is some further reading on pointers to member functions: https://isocpp.org/wiki/faq/pointers-to-members
Edit:
I just realized, that XSetErrorHandler does not accept functors, but only function pointers https://tronche.com/gui/x/xlib/event-handling/protocol-errors/XSetErrorHandler.html. In this case, WindowHandler::catch_error must be static. You can only treat a lambda as a function pointer, if it does not capture anything.
If you really want to capture the error_flag in a member of WindowHandler, the only option I see for you is to have one global instance of WindowHandler (a so-called singleton). Then the static catch_error function can set the member of this singleton, no implicit this argument is required.
Note that global variables and singletons are discouraged and should be avoided if possible. There are some situations, where this is not possible. Logging and error handling are often in these scenarios.
#include <iostream>
#include <memory>
struct Display {};
struct XErrorEvent {};
void XSetErrorHandler(
int (*handler)(Display *, XErrorEvent *)
) {}
class WindowHandler
{
private:
// constructor is private: No other class should be allowed to construct instances
WindowHandler() = default;
int catch_error_impl(Display*, XErrorEvent*) {
std::cout << "Error happened\n";
error_flag = 1;
return 0;
}
public:
// don't copy or move a singleton
WindowHandler(WindowHandler const&) = delete;
WindowHandler(WindowHandler&&) = delete;
// the global WindowHandler singleton gets instantiated the first time the get_instance_ptr function is called
static WindowHandler* get_instance_ptr() {
// calling new in the argument of unique_ptr ctor is ok. memory is freed when the dtor is called
static auto handler = std::unique_ptr<WindowHandler>(new WindowHandler());
return handler.get();
}
static int catch_error(Display* disp, XErrorEvent* xe) {
return get_instance_ptr()->catch_error_impl(disp, xe);
}
int error_flag {0};
};
int main()
{
XSetErrorHandler(WindowHandler::catch_error);
std::cout << WindowHandler::get_instance_ptr()->error_flag << std::endl;
}
https://godbolt.org/z/MTWcfK3bs
I would like to know Why have to make fun1() as static member function? function pointer in template? in below piece of code.
#include<iostream>
using namespace std;
class A
{
int temp;
public:
A():temp(1){}
template<class T, void (*fn)(T* )>
static void create(T *ptr)
{
cout <<"create fn"<<endl;
//fun1(ptr);
}
static void fun1(A* tp)
{
cout<<"func temp"<<endl;
}
static void fun2(A& ob)
{
cout<<"fun2 start"<<endl;
A::create<A,&A::fun1>(&ob);
cout<<"fun2 end"<<endl;
}
};
int main()
{
A ob,ob1;
ob.fun2(ob1);
}
A static function member of a class is simply a regular function in the class's namespace:
Static members of a class are not associated with the objects of the class: they are independent objects with static storage duration or regular functions defined in namespace scope, only once in the program.
cppreference.com
In your example, the type of A::f1 would be void(A*) and the type of A::f2 would be void(A&). Notably, static functions do not need an instance to be called.
Alternatively, non-static member functions do require an instance to be called. You would have to use pointers to class members. In your example, you would use &A::f1 and &A::f2 and their types would be (void)A::*f1(A*) and (void)A::*f2(A&) respectively. If pointers to member functions were treated as regular function pointers, how would they be called? They would need an object instance for the this pointer to point to.
You can convert a pointer to a member function to an object that overloads the () operator and behaves like a function (AKA a functor) using std::bind:
A a;
std::bind(&A::f1, &a); // &a is the value of this
However, functors do not have the same type as function pointers. I recommend using std::function in the functional header file instead of function pointers because they accommodate for functors.
(See http://en.cppreference.com/w/cpp/language/pointer for more information.)
in C++ classes, if I have a constant function (In my understanding constant functions are classes that cannot change anyting in the class, hope this is true)
for example a function like this
int output(int value) const
Am I allowed to call a function within this function remove that actually changes anything in the class?
For example lets say I have a variable called number in private.
my output function adds one to the variable number, but not directly, it calls
a non constant function called addOne which adds one to the variable number.
I notice that I am getting an error when a output function is calling addOne(I know that output function is const but it modifies a value, but it modifies it indirectly). I wonder why I am getting an error, what error compiler actually detects here?
Thank You, and sorry if my question is hard to understand.
Thank you all for answering.
The answer is simple - no, you cannot. Every class method is a function that implicitly passes this as a parameter. When you declare a method as const, that means that it will actually pass const this to this function. It is both correct logically and syntactically not to call not const methods from const methods.
const instances can only call const functions. Say:
class YourClass {
...
int output(int value) const;
int regularMethod(); // Non-const
...
};
is your class with a const function. And the variables:
const YourClass obj1;
YourClass obj2;
Here obj1 can call output method while it cant call regularMethod. obj2 can call both.
Every const function() is getting a const this pointer as a default parameter, so you cannot change a member variable of a class even if you try to call a non_cost function from a const function and try to modify a member variable.
So if you try to call a non const function from a const function, you will get compile error.
The answer is NO. The long answer is perhaps YES, provided you use an abomination like this, via const_cast-ing this in the const calling function (but you have to make sure you invoke your function on non-const objects, otherwise it leads to undefined behaviour):
#include <iostream>
struct Foo
{
int x = 0;
void f()
{
++x;
}
void modify_x() const
{
const_cast<Foo*>(this)->f(); // call non-const member function
}
};
int main()
{
Foo foo;
std::cout << foo.x << std::endl;
foo.modify_x();
std::cout << foo.x << std::endl;
}
A C header of interest (some_external_library.h) declares the following struct, containing a function pointer:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
void (*function_ptr)(void);
} fp_test;
/* ... */
#ifdef __cplusplus
}
#endif
When some interesting event happens in some_external_library.c, this function pointer gets called.
I would like to set up a pointer to an instance of this struct in an instance of a C++ class called Foo, and then set the value of function_ptr to the address of a non-static function with the instance of Foo. In other words, I want my C++ code to define what this function pointer does.
For instance, here is a class declaration (foo.h):
class Foo {
public:
fp_test *fp_test_ptr;
void setup(void);
void breakdown(void);
void my_callback(void);
};
There are three functions: a setup function to initialize values, a breakdown function to release any pointers or objects, and a simple my_callback function, which takes and returns no arguments.
Here is the class definition (foo.cpp):
int main(int argc, char** argv) {
Foo some_foo;
some_foo.setup();
some_foo.breakdown();
return EXIT_SUCCESS;
}
void Foo::setup(void) {
fp_test_ptr = new fp_test;
fp_test_ptr->function_ptr = &Foo::my_callback;
}
void Foo::breakdown(void) {
delete fp_test_ptr;
}
void Foo::my_callback(void) {
std::fprintf(stderr, "Callback called...\n");
}
When I compile this, I get the following error:
foo.h:: error: assigning to 'void (*)()' from incompatible type 'void (Foo::*)()'
fp_test_ptr->function_ptr = &Foo::my_callback;
^------------------
I tried casting this call, but I get an error message indicating that I cannot cast from type void (Foo::*)() to void (*)().
How might I set up a non-static method in C++ to be a function pointer to a C library?
I was able to get a static version of Foo::my_callback() to compile, but I don't think I can use a static method for my needs, as I will not have access to the states of non-global members in the class instance some_foo, only the values of global members.
Is there a way to do this with a non-static function?
The normal way around this is to have two one functions: one static and one member function and to pass the object instance as a parameter
class Foo {
public:
fp_test *fp_test_ptr;
void setup();
void breakdown();
void my_callback();
static void _my_callback(void* self);
};
void Foo::_my_callback(void* self)
{
reinterpret_cast<Foo*>(self)->my_callback();
}
Change the C signature of the function pointer to
void (*function_ptr)(void*)
When you call it, pass the object instance as the parameter.
Edit:
To call from C, presumably you need to know which object it refers to so somehow, you need a method of passing the C++ instance to C.
Foo* fu1 = new Foo();
Foo* fu2 = new Foo();
/* fu1 and fu2 need to be passed to the C program */
...
/* Setting up */
fp_test pointerTest;
pointerTest.function_ptr = Foo::_my_callback;
...
/* Calling */
pointerTest.function_ptr(fu1);
pointerTest.function_ptr(fu2);
It is not possible. Every non-static c++ member function has a hidden "this *" parameter. So the function signature will always be different.
I need to use a function defined in one class in another class. Instead of rewriting the whole function, I tried to pass the function as a pointer, as below:
class C {
public:
int get(int x) { return x*x; }
};
struct S {
int (*func) (int x);
};
int main() {
C c;
S s;
cout << c.get(3) << endl;
s.func = &C::get;
cout << s.func(3) << endl;
return 0;
}
This doesn't work and gives the following error:
func_ptr.cpp: In function ‘int main()’:
func_ptr.cpp:42:18: error: cannot convert ‘int (C::*)(int)’ to ‘int (*)(int)’ in assignment
Is it possible to do something like this, and if so, how can I fix it? Moreover, if it is possible, can I use the pointer from an object instance instead of the class? That is, to possibly use variables defined in a specific class instance. Thanks.
C::get() is a non-static member function, which means it must be invoked on an instance of C. It has an implicit first argument, the this pointer, that must be passed to it when calling the function.
Since your C::get() doesn't seem to need access to any data members of C, you could make it a static member function.
static int get(int x) { return x*x; }
Now your code will work as is.
Another option is to change func so that it is a pointer to a member function of C
struct S {
int (C::*func) (int x);
};
And invoke it as
s.func = &C::get;
std::cout << (c.*(s.func))(3) << std::endl;
Yet another option would be to change the type of S::func to std::function<int(int)>. Now it can hold any callable (function pointer, functor, lambda) that takes a single int as an argument, and returns an int.
struct S {
std::function<int(int)> func;
};
s.func = std::bind(&C::get, &c, std::placeholders::_1);
std::cout << s.func(3) << std::endl;
A regular function and a member function are a bit different. To use a member function, you'll need an object to call it on (i.e. the this pointer in a member function body).
Take a look at std::function and std::bind, they are used to handle function like (callable) entities in a uniform way. They can manage global functions, static member functions, lambdas, regular member functions, functors, whatever that can be called like a function.
http://en.cppreference.com/w/cpp/utility/functional/function
http://en.cppreference.com/w/cpp/utility/functional/bind
http://en.cppreference.com/w/cpp/header/functional
e.g.:
struct S
{
std::function<int(int)> func;
};
C c;
S s;
s.func = std::bind( &C::get, &c, std::placeholders::_1 );
If you're OK with using STL then you can utilize std::function to hold a pointer to a function and std::bind to bind that particular pointer to a particular function. It makes your code look much more cleaner. std::bind looks for both static and non-static member functions. For non-static member function would need to pass the object reference so it will be able to point to the correct address.
Here is a code snippet to show how to use it:
std::bind(ClassName::MemberFunctionName, object, std::placeholders::_1)
std::placeholders::_1 means that ::MemberFunctionName accepts one parameter.