How to call pointer member function inside a class definition? - c++

How do I call a pointer member function within a class definition?
My code:
//Myclass.h
struct Booking{
int src;
int dest;
int pos;
};
class MyClass{
public:
void ExecutePlan();
private:
struct FlightPlan{
string name;
vector<Booking> bookings
};
typedef FlightPlan FP;
FP firstplan;
FP secondplan;
void FirstPlan(Booking& book);
void SecondPlan(Booking& book);
void Execute(FP& fplan, void (MyClass::*mptr)(Booking& book));
};
// Myclass.cpp
void MyClass::FirstPlan(Booking& book){
// do something with booking
}
void MyClass::SecondPlan(Booking& book){
// do something with booking
}
void MyClass::Execute(FP& fplan, void(MyClass::*mptr)(const FlightPlan& fp)){
for (int i=0; i<.fplan.bookings.size(); i++){
cout << "Executing Plan: "<< fplan.name << endl;
// Problematic line ...
mptr(bookings[i]); // <----- can't compile with this
}
}
void MyClass::Execute(){
// is this the correct design to call this member functions ???
Execute(firstplan, &MyClass::FirstPlan)
Execute(secondplan, &MyClass::SecondPlan)
}
How can i structure the Execute Function to receive a member function as a pointer?
Pls: Am a newbie in C++, maybe the design is weird!!
Paul

How to call pointer member function inside a class definition?
Unlike member names, member pointers aren't implicitly applied to this. You have to be explicit:
(this->*mptr)(fplan.bookings[i]);
is this the correct design to call this member functions ???
Apart from a few obvious errors (such as missing ; here and there, saying const FlightPlan& where you mean Booking& in the definition of Execute), the rest of the code looks fine. Specifically
Execute(firstplan, &MyClass::FirstPlan)
Execute(secondplan, &MyClass::SecondPlan)
is the correct syntax for obtaining the member-function pointers.

The operator to call a member function pointer is ->*. Since you want to call it on this object, you need to use
(this->*mptr)(bookings[i]);

Related

VOID pointer De-referencing using -> [duplicate]

I have the following code (live on Coliru):
// untouchable extern library .hpp file
typedef union ExternLibraryUnion
{
int a;
float b;
}ExternLibraryUnion;
// my code
#include <iostream>
class Container{
public:
Container() : m_union(NULL) {};
~Container(){
if(m_union){
delete m_union;
}
}
void init(){
m_union = new ExternLibraryUnion();
}
ExternLibraryUnion* get_union(){
return m_union;
}
private:
ExternLibraryUnion* m_union;
};
class Master{
public:
Master() : m_union(NULL) {
m_container.init();
};
~Master(){
if(m_union){
delete static_cast<ExternLibraryUnion*>(m_union);
}
}
void load(){
}
void set(int i){
m_union = m_container.get_union();
m_union->a = i;
}
void* get_union(){
return m_union;
}
private:
void* m_union;
Container m_container;
};
class Worker{
public:
Worker() : m_extern_library_union(NULL) {};
~Worker(){
if (m_extern_library_union){
delete m_extern_library_union;
}
}
void load(Master& master){
m_extern_library_union = reinterpret_cast<ExternLibraryUnion*>(master.get_union());
}
int get_int(){
return m_extern_library_union->a;
}
private:
ExternLibraryUnion* m_extern_library_union;
};
int main()
{
Master master;
master.set(3);
Worker worker;
worker.load(master);
std::cout << worker.get_int() << std::endl;
}
The code produces:
main.cpp: In member function 'void Master::set(int)':
main.cpp:55:16: error: 'void*' is not a pointer-to-object type
m_union->a = i;
^~
In an extern library, a union ExternLibraryUnion is defined which I'm using inside my own code. My problem, which I can't get my head around, is in the set method of class Master. The Master member void* m_union should point to the union stored inside the member Container m_container. As I'm setting the m_union = m_container.get_union() the compiler should be able to know that I'm getting a ExternLibraryUnion* back from the get_union() method call. So I don't quite the error arising from the assignment m_union->a = i. Sure, a void* has no type, but I assigned it a pointer of the precise type ExternLibraryUnion.
Let's also say I can not touch the Container m_container object directly. I need to make the assigned through the void* m_union pointer.
Any help is highly appreciated!
The compiler has no clue what m_union might actually be pointing at. You declared it as a void * so the compiler believes you, it has no choice. And that's all it knows, so m_union->a has to be flagged as an error, because ->a has no meaning to the compiler here.
To put it another way, RTTI aside, pointers don't 'know' what they're pointing at. The compiler only knows how the pointer was declared.
I don't know what else to say, it's really that simple. I don't like having to say this, but looking at the code as a whole, it looks like a complete mess. Who wrote it?
[Edit] And what Jeffrey said will indeed fix it, but that's not what you asked.
You need to change
private:
void* m_union;
to
private:
ExternLibraryUnion* m_union;
at line 63. As your code stand, you upcast the pointer to void*, and then, at the next line the compiler can't know the pointed type.
If you can't change the type, you can static_cast the void pointer to an
ExternLibraryUnion*. Then use that to access. Since you know the type, the static_cast could be "acceptable". But not the nicest design by any measure.

tuple of void member functions

I'm attempting to create a tuple which contains a pointer to a void member function, but I'm having trouble making it work.
here's my code:
class A
{
void dostuff(){ cout<<" doing stuff "}
};
class B
{
A* aobj;
typedef vector<vector<tuple<int,int,void(A::*)()>>> sequence;
sequence Sequence;
void getinfo(int n1, int n2, void(A::*func)())
{
Sequence.resize(1);
Sequence[0].push_back(make_tuple(n1,n2,(aobj->*func)()))//<--ERROR HERE
};
};
it's giving me the error "invalid use of void expression."
I also tried to simplify the function to :
void getinfo(void(A::*func)())
{
make_tuple((aobj->*func)());
}
and it still gives me the same error.
As Igor Tandetnik pointed out, (aobj->*func)() was calling the method and returning void to the make_tuple() function. To pass a member pointer, it should instead be make_tuple(n1,n2,func).

Outputting member type of a vector of types

I have a vector of unique_ptr<my_class> and would like to be able to pass to a function the member variable of this class I'd like to output. This vector is part of a class in itself.
For example I would like to
void my_top_class::output_member(sometype var_to_output, std::ofstream &out)
{
// Iterate over the vector and output the member variable
out << my_class->var_to_output << std::endl;
// Or something similar
}
And then just do
my_top_class.output_member(var1, file_out);
my_top_class.output_member(var2, file_out);
At the moment I have a separate function for each member variable and this feels cumbersome
Use pointer to data members (it is only an example, you should adopt it to your situation):
template <typename MemberType>
void output_member(const MyClass& my_object, MemberType MyClass::* var_to_output)
{
std::cout << my_object.*var_to_output << std::endl;
}
Here .* is one of pointer to member access operators.
Example of using:
struct MyClass
{
int member_variable_;
};
// ...
MyClass my_object{42};
output_member(my_object, &MyClass::member_variable_);
Live demo
Maybe just create a new class that you will use to store your elemets? Like this:
class Memory
{
private:
std::vector<yourclass> vec;
public:
std::vector<yourclass> getVector()
{
return vec;
}
};
Then create an object of that class in your main class main window, whatever you are using. Actually you didn't provide too much information and it is hard to answer your question.

How can I pass a member function pointer into a function that takes a regular function pointer?

I have a player class which looks like this (stripped down to what is needed for this problem):
class Player
{
public:
Player();
~Player();
void kill();
void death();
void reset();
};
The kill(), death(), and reset() functions look like this:
void Player::kill()
{
void (*dPtr)() = &death;
Game::idle(dPtr, 48);
}
void Player::death()
{
reset();
}
void Player::reset()
{
//resets
}
The idle function is a static memeber function of Game, which takes a function pointer and an integer n, and calls the function after n tick. Here is the function, the implementation shouldn't matter:
class Game {
static void idle(void (*)(), int);
};
This code gives me the error:
ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&Player::death' [-fpermissive]
So I change the line from
void (*dPtr)() = &death;
to
void (Player::*dPtr)() = &Player::death;
to solve that issue. But then my call to the idle function is incorrect, as it takes a regular function pointer, and I am passing in a member function pointer, and thus gives me the error:
no matching function for call to 'Game::idle(void (Player::*&)(), int)'
So my question is:
How can I pass the member function pointer Player::*dPtr into the idle function, which takes a void (*)() as an argument?
Or is there another way I can solve my previous error which forbids me from taking the address of an unqualified member function to form a pointer to a member function?
Another answer mentions that you need two pointers. However C++ already comes with containers for doing just this, so it would make your code a lot simpler to use those. (In C++03, some of the std:: items below were std::tr1::).
Sample code:
#include <iostream>
#include <functional>
struct Game
{
static void idle( std::function<void()> func, int x )
{ std::cout << "x = " << x << "\n"; func(); }
};
struct Player
{
void death() { std::cout << "player.death\n"; }
void kill() { Game::idle( std::bind(&Player::death, this), 48 ); }
};
int main()
{
Player p;
p.kill();
}
Lifetime note: std::bind binds by value. Using *this means a copy of the Player is made and stored in the std::function object, copied around with it as necessary.
Using this means the function object stores a pointer, so if you actually store the function object in Game::idle you must take care that this Player is not destroyed before removing this function object from Game::idle's list.
To call a member function through a pointer, you need two pointers: the pointer to the function itself, and a pointer to an object to be this. Your Game::idle API does not support this usage. You need to change it so that it passes at least one argument (conventionally of type void *) to the callback. Then you can use the following pattern:
struct Player
{
// ...
void kill();
// ...
static void call_kill(void *self);
};
void Player::call_kill(void *self)
{
static_cast<Player *>(self)->kill();
}
struct Game
{
static void idle(void (*)(void *), void *, int);
};
void Game::idle(void (*callback)(void *), void *arg, int ticks)
{
// ...
callback(arg);
// ...
}
void kill_player_delayed(Player *p, int ticks)
{
Game::idle(Player::call_kill, static_cast<void *>(p), ticks);
}
You have to write a static call_X method for every instance method X you want to call.
An alternative approach, which is arguably more C++-idiomatic and flexible, and involves less explicitly written-out code, but has higher runtime costs (three indirect function calls and a heap allocate-free cycle per invocation, instead of a single indirect function call), is to have Game::idle take an object of a particular class, with a virtual callback method. That class is then given a template subclass that can call anything that implements operator(), such as the result of std::bind.
struct Runnable { virtual ~Runnable(); virtual void invoke() = 0; };
template <typename T> struct TRunnable : Runnable {
TRunnable(T target) : target(target) {}
void invoke() { target(); }
private:
T target;
};
template <typename T> TRunnable<T>* make_Runnable(T obj)
{ return new TRunnable<T>(obj); }
struct Game
{
static void idle(Runnable *, int);
};
void Game::idle(Runnable *r, int ticks)
{
// ...
r->invoke();
delete r;
// ...
}
struct Player
{
// ...
void kill();
// ...
};
void kill_player_delayed(Player *p, int ticks)
{
Game::idle(make_Runnable(std::bind(&Player::kill, p)), ticks);
}
You cannot make Game::idle take the result of std::bind directly because that object's type is unspecified (and varies depending on how you call std::bind), so it can only be used as an argument to a template function call. A virtual method call to an adapter class is the only way to keep Game::idle compiled out-of-line and still let it use bound-call objects.
In either approach, beware object lifetime issues. In particular, if Game::idle does not call its callback before returning, you need to
make sure that both the original object, and (in the second approach)
the object returned by make_Runnable survive until the callback fires. This is why make_Runnable uses new.
Because I really don't like the answer that casts void*'s to other objects (almost never necessary in C++!) and nobody has posted an answer using the suggestions in the comments I'm going to suggest this.
Use a templated type for your callback!
Like this:
class Game{
template<typename Func>
static void idle(Func &&func, int i){
// game stuff
func();
// other game stuff
}
};
Then you don't lose all of your type safety (casting void*) and it should be the fastest solution.
Also, where you are assigning a function pointer, you can change the code to be far more readable in this case:
void Player::kill(){
Game::idle([this](){this->death();}, 48);
}
Which is far nicer than having to write the correct function pointer type.
You cannot do that simply because pointer to [static] function is a single pointer sizeof void*. In contrary member function need more information, e.g. two pointers: one for this and another one for the function itself so member function pointer has sizeof > sizeof(void*).
Therefore you have two options:
to change signature of your idle() to this void idle(void (*)(), void*, int); so you will be able to pass this somehow.
Or make static variable that will hold this pointer. But that assumes that only one death() can be at idle queue at any given moment of time.
1) is what people do usually in such cases.

function pointer - ambiguous symbol error

MyClass is a singleton class (There will only ever be one of these in my whole program).
What I want to do is follows.
Add data to my class using AddData, get a function pointer returned that I can then pass to 'another' function in a dll.
Then this 'other' function calls my call back function
My class is like so.
typedef void (*DataReceivedCallback)(int, int);
class MyClass
{
MyClass();
~MyClass();
void AddData(int sourceId, DataReceivedCallback &callback);
static void MyCallBackFunction(int var1, int var2);
};
void MyClass::AddData(int sourceId, DataReceivedCallback &callback)
{
callback = &MyCallBackFunction;
}
void MyClass::MyCallBackFunction(int var1, int var2 )
{
//do something blah blah
}
I can then do:
int main()
{
DataReceivedCallback callback;
MyClass->GetInstance()->AddData(1, callback);
callback(1,100);
}
When I step through this I see that I do actually step into the callback MyCallBackFunction which is what I want :)
What I then want to do now is pass this 'callback' defined in main to a dll function that will call back into my callback function.
I have the code for the dll so I want to modify one if its functions so that it accepts my callback function parameter.
I am doing this in the dll function signature:
void * someDllFunction( int var1, int var2, DataReceivedCallback& callback)
{
callback(2, 200);
}
But I get the error:
error C2872: 'DataReceivedCallback' : ambiguous symbol
How can I solve this?
Does this have to do with only being allowed to use c-style parameters across dll boundaries??
typedef void (*DataReceivedCallback)(int, int);
should be,
typedef void (MyClass::*DataReceivedCallback)(int, int);
Because, MyCallBackFunction is a non-static member method of MyClass. So it cannot have regular function signature.
Also change assignment to,
callback = &MyClass::MyCallBackFunction;
Demo.
You got your types wrong. DataReceivedCallback, alias void(*)(int, int), is a function pointer, but &MyClass::MyCallBackFunction is a pointer-to-member-function (PTMF). Those two are entirely unrelated and incompatible types!
You cannot treat a member function as a free function.
Since you only have one single instance of your class (Note: "one instance", not "one class"; you always only have one class), why bother with member functions at all? Just make the function global (inside a namespace) and you're done. Though perhaps I'm misunderstanding your requirements.
Another note: You don't need to pass function pointers by reference to the DLL function, just pass them by value. They're just pointers, so they're light-weight.
The thing you are missing is how to declare a pointer to member function and how to invoke the member function via that pointer, below is a working example based on your example:
class MyClass;
//standard way to declare a pointer to member function should be - className::*memberFunName(para list)
typedef void (MyClass::*DataReceivedCallback)(int, int);
class MyClass
{
public:
void AddData(int sourceId, DataReceivedCallback &callback);
void MyCallBackFunction(int var1, int var2);
};
void MyClass::AddData(int sourceId, DataReceivedCallback &callback)
{
callback = &MyClass::MyCallBackFunction;
}
void MyClass::MyCallBackFunction(int var1, int var2 )
{
//do something blah blah
int tem = var1 + var2; //tem = 3 here
}
int main()
{
MyClass obj;
DataReceivedCallback callback;
obj.AddData(1, callback);
(obj.*callback)(1,2); //standard way to call the member function via function pointer
}