This question already has answers here:
C++ class member function pointer to function pointer
(4 answers)
Closed 2 years ago.
I have two classes, say A and B; I want to store a function pointer of B in a wrapper function<void()> in A.
The ultimate goal is to be able to call OnRender() at multiple places in A, but OnRender() is defined at runtime (say I want to choose one B among many).
How could this be done ?
class A
{
public:
function<void()> OnRender{}; // I want to use this
void (B::*OnRender)(){}; // I want to avoid this
}
class B
{
public:
auto SomeJob() -> void;
}
I could store a function pointer like this:
someA.OnRender = &B::SomeJob;
// OK if I use void (B::*OnRender)(){};
But I also want to avoid referencing the class B in A.
ANSWER:
I can store a lambda like this:
someIntanceOfA.OnRender = [&](){ someB->SomeJob(); };
// OK if I use function<void()> OnRender{};
Or with safety measures:
someA.OnRender = [&](){ if(somB != nullptr) someB->SomeJob(); };
Function pointer to a non static class member method cannot be typecasted to normal non-class--method function pointer. If done, it's an undefined behaviour and most certainly results in crash.
The reason is that, an object of that class is required to invoke it's method.
Your conventional pointer to member syntax is better.
Refer:
Casting between void * and a pointer to member function
casting member function pointer
C++ class member function pointer to function pointer
Related
This question already has answers here:
How can I pass a member function where a free function is expected?
(9 answers)
how to pass a non static-member function as a callback?
(8 answers)
Pass Member Function as Parameter to other Member Function (C++ 11 <function>) [duplicate]
(2 answers)
Closed 4 months ago.
I need to change the prototype of a function pointer of a class. So, I was hoping inheriting it and doing the following would work, but it doesn't ("invalid use of non-static member function 'void B::myIntCallback(unsigned int)"):
class A {
public:
typedef void (*intCallback_t)(unsigned int myInt);
A(intCallback_t intCallback) {}
};
class B : A {
public:
typedef void (*charCallback_t)(unsigned char myChar);
B(charCallback_t charCallback) : A(this->myIntCallback) {
charCallback_ = charCallback;
}
private:
charCallback_t charCallback_;
void myIntCallback(unsigned int myInt) {
charCallback_((unsigned char)myInt);
}
};
Does anybody know how I can solve this? I can't change class A.
You are trying to pass a member function (B::myIntCallback) to a function pointer argument. Since the member function needs an object to be called on, his would require some kind of capturing, e.g. a lambda capturing this or an std::bind expression. Unfortunately, neither is possible with a plain function pointer, see also Passing capturing lambda as function pointer.
If possible, you may want to consider changing the class A to accept either a std::function or a template argument as the type of the callback. See also Should I use std::function or a function pointer in C++?.
This question already has answers here:
C++ Call Pointer To Member Function
(4 answers)
Calling C++ member functions via a function pointer
(10 answers)
Closed 9 months ago.
Consider this class:
class Downloader {
private:
bool video_or_audio;
// other variables [...]
// [...]
void downloadVideo(std::string videoURL);
void downloadAudio(std::string audioURL);
public:
void download();
}
Now, download() is defined this way:
void Downloader::download(){
std::ifstream url_list;
void (*download_func)(std::string) = video_or_audio == 0 ? downloadVideo : downloadAudio; // Compiler says here: "Reference to non static member function must be called".
if(video_or_audio == 0){
url_list.open("video_list.txt");
}
else{
url_list.open("audio_list.txt");
}
std::string url;
while(std::getline(url_list, url)){
download_func(url); // Calling the function pointed by the pointer defined in line 2 of the function download().
}
}
My compiler (clang) says: "Reference to non static member function must be called" in the second line of function download() definition. Why is this happening and how can I solve this problem?
A solution appears to be defining downloadVideo() and downloadAudio() functions to be static in the class declaration. However, if I do so, I cannot access private variables members of class Downloader, that's not desirable, as I need these variables.
Thank you!
Once calling a member function by pointer, you need to provide two things:
Member function itself
Address of particular instance of given class at which the member function to be called (because the function can access class members thus you have to advise which of the instances is the right one)
void (Downloader::*download_func)(std::string) = video_or_audio == 0 ? &Downloader::downloadVideo : &Downloader::downloadAudio; // Correct the signatures.
...
while(std::getline(url_list, url)){
(this->*download_func)(url);
}
So, here we changed download_func from "just function pointer" to a member function pointer. Then, later in the loop body, we call this member function on this instance (however you can pass an instance as a param if necessary).
This question already has answers here:
Using generic std::function objects with member functions in one class
(6 answers)
Closed 5 years ago.
What is the approach to have a vector to schedule method calls of a class. I would like to have a vector of methods, something like this:
class Model {
using task_t = std::function<void()>;
std::vector<std::vector<task_t>> _frameTasks;
void add_function() { _frameTasks[3].push_back(&(this->function()); }
void function() {std::cout << "hi"; }
void step() {
for (auto task : _frameTasks[3]) task();
}
}
But the compiler complains that:
error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.
How could I solve this issue or what is the right approach?
&(this->function()) is applying & to the result of the call to the function() member function. The default operator& requires an lvalue, however, the expression this->function() is not an lvalue.
Writing &Model::function won't work either because it is a pointer to a member function (as opposed to a pointer to a function). Its type is void (Model::*)(), i.e.: a pointer to a Model's (non-static) member function that takes no parameters and returns nothing.
You need some way to specify the Model object on which the function() member function will be called.
Since C++11 you can achieve that by simply using a lambda expression:
void add_function() {
_frameTasks[3].push_back(
[this](){ add_function(); }
);
}
This question already has an answer here:
Factory Pattern: typedef Class *(createClassFunction)(void)
(1 answer)
Closed 8 years ago.
I've come across a declaration inside a C++ Struct{..} that I've never seen before.
Can anyone tell me what it means;
struct DerivedMesh {
char cd_flag;
void (*calcNormals)(DerivedMesh *dm); // <-- What is this?
It kind of looks like it's dereferencing a pointer called calcNormals, but that's all I can make out.
This is a C syntax for declaring function pointers.
In this particular example, DerivedMesh will have a member calcNormals that is a pointer to a function accepting single argument of type DerivedMesh*. It can be called like an ordinary function:
void foo(DerivedMesh* dm) { ... }
DerivedMesh dm;;
// Init members and set calcNormals to actual function
dm.cf_flag = whatever;
dm.calcNormals = foo;
dm.calcNormals(&dm); // calls foo
This
void (*calcNormals)(DerivedMesh *dm);
is class data member definition with name calcNormals that has type of pointer to function of type void( DerivedMesh * )
This question already has answers here:
Difference between “::” “.” and “->” in c++
(5 answers)
Closed 9 years ago.
I am new to programming in c++.Can you please explain (with example if possible) in which case . and -> have to use when accessing variable from a class
:: is the scope resolution operator, used for referencing static class members and namespace elements.
-> is the indirect reference operator, used for referencing members methods and fields on an instance pointer.
. is the direct reference operator, used for referencing member methods and fields on an instance.
if you have pointer use -> if you have object or reference use . e.g. Say I have:
class foo{
public:
int a;
}
int main()
{
foo f;
foo* f1 = new foo();
cout<<f.a<<"\n"<<f1->a<<"\n";
}
If you have a pointer type and you want to access a member object or member function you can use (*ptr).anything or ptr->anything. In most cases that's exactly the same (unless of course a specific -> operator is overloaded). If you have a non pointer type you should use ..
This is simple, these both operators are used by an instance to access members or methods.
. is used by instance or instance reference
-> is used by instance pointer
In Example:
class MyClass
{
public:
int a;
}
int main()
{
// Instance, Reference, and Pointer declaration
MyClass instance;
MyClass& instanceReference = instance;
MyClass* instancePointer = new MyClass();
// Usecases
int a;
a = instance.a;
a = instanceReference.a;
a = instancePointer->a;
}