Skip to main content
gamedev.net
🔒 Locked

Converting a member function * to a function*?

Started by Promit Jul 17, 2003 at 12:00 AM 15 replies 750+ views
Original Post
Promit
Promit
Ok, now I've been told a million times this can't be done, but I still can't accept it. Although most of you can probably guess what spawns this question in the first place, I mean it in a far broader sense. When you have a member function pointer, it is not a pointer to a specific place in memory because there is a seperate one for each instance of the class (i think...). What bothers me is, for each instance of a class , that function should have a quite specific memory location. Shouldn't it be somehow possible to cast this to a static pointer to a function, maybe with the implicit this pointer passed explicitly or something? Because the function's location is known, even if it doesn't quite meet the definition used in the class def... I'm sure that this will require some obscene hack to pull off, but that's ok. I just want to see if there is any possible way of getting a non-member function pointer to a specific instance of a member function. If I'm wrong about there being multiple instances of a function, and it really depends entirely on the implicit this pointer, then shouldn't it be possible to cast the member func pointer to a regular func pointer with an explicit pointer passed at the end (or beginning?) of the argument list? No matter how much I think about it, I still think it ought to be possible to hack this out, somehow... [edited by - Promit on July 17, 2003 1:00:41 AM]
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Ravyne
Ravyne
There are not seperate instances of member functions, only non-static member data is duplicated. for example if you have:

...
ClassX A;
ClassX B;
...

you will have 2 sets of member variables and one set of member functions, as well the shared static member variables.

There WILL be 2 sets of member functions if there is a template involved. like so, each one specified to their template type:

...
ClassX A;
ClassX B;
...

I'm not sure when a class is derived from another class whether the derived-from class's member functions are duplicated locally in the derived class or not. I believe they would be (at least some of them), because they can be overidden(spelling?) in the derived class.

[EDIT] more specific.

Ravyne, NYN Interactive Entertainment
[My Site][My School][My Group]

[edited by - ravyne on July 17, 2003 1:26:26 AM]
throw table_exception("(? ???)? ? ???");
Egroth
Egroth
I believe that member function are stored in a programs code segment. And the data part of the code is sotred on the heap or stack depending on how it is stored. theirfore it would be imposible to cast a member function pointer to a function pointer because member function require a pointer into the data segment for the this pointer.
Yanroy
Yanroy
It's not impossible to do this cast. I remember seeing someone else do it on these forums once (or maybe it was in #gamedev). I believe you do have to explicitly pass the this pointer. I'm sure if you look at the assembly code your compiler produces when it calls a member function, you can figure it out. At worst, you'll have to call the member function from ASM instead of finding a C++ equivalent statement

--------------------


You are not a real programmer until you end all your sentences with semicolons; (c) 2000 ROAD Programming

You are unique. Just like everybody else.

"Mechanical engineers design weapons; civil engineers design targets."
"Sensitivity is adjustable, so you can set it to detect elephants and other small creatures." -- Product Description for a vibration sensor

Yanroy@usa.com

[edited by - Yanroy on July 17, 2003 9:09:37 AM]

--------------------

You are not a real programmer until you end all your sentences with semicolons; (c) 2000 ROAD Programming
You are unique. Just like everybody else.
"Mechanical engineers design weapons; civil engineers design targets."
"Sensitivity is adjustable, so you can set it to detect elephants and other small creatures." -- Product Description for a vibration sensor
Leffe
Leffe
This might have been said already:

This is what a member function looks like in the code:

int CClass::Function(int a, int b) { ... }

But this is what it really is:

int Function(CClass * this, int a, int b) { ... }


I don''t really thing you can do much about it though... without some assembly ^_^
sbennett
sbennett
quote:
Original post by Leffe
This might have been said already:

This is what a member function looks like in the code:

int CClass::Function(int a, int b) { ... }

But this is what it really is:

int Function(CClass * this, int a, int b) { ... }


I don''t really thing you can do much about it though... without some assembly ^_^

VC++ does it slightly differently: the this pointer is passed in a register, not on the stack with the other arguments.

Of course, what you could do is write a function that takes a pointer-to-member and an object pointer, and then generates a function which calls that method on the given object. Of course, you would then have to delete the function when you''re done with it. Fun.
antareus
antareus
quote:
What bothers me is, for each instance of a class , that function should have a quite specific memory location.

NO . Do you think that when you make an object it copies the code for every instance? How wasteful is that? It doesn''t do that. The object itself is stuffed into the this pointer as the first argument.

quote:
Original post by risingdragon3
boost::function.

It really doens''t get any easier than boost::function and boost::bind.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
Promit
Promit
Even so, it has a known this pointer (i confused myself before, damnit).

Is there any way to do this in pure C/C++, or must one sink into asm?
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
sbennett
sbennett
quote:
Original post by Promit
Is there any way to do this in pure C/C++, or must one sink into asm?


Either use boost, write your own version of the boost classes, or sink into ASM.

Yes, there is a way to do this in pure C++, but you''ll have to use a class to wrap the function pointer and the ''this'' pointer together. I would suggest using the boost classes, it''ll save you writing your own.
Sneftel
Sneftel
You CANNOT cast between a member function and a nonmember function. The calling conventions are different... the member function wouldn''t know what to do with the values passed into it by something that thought it wasn''t a member function, and vice versa. The only way to do this is with an adapter.
antareus
antareus
Boost *is* pure C++. Boost.Function, which you''re asking for, will be in the next version of C++. Is that satisfactory?

(I really get tired of people preferring to use implementation-dependent or assembly hacks which must be debugged and tested instead of actually using someone else''s code to get the job done -- especially when the someone else in question are members of the C++ Standards Board that made the language in the first place.)
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
Promit
Promit
I haven;t had a chance to look at it, but in short, what exactly is Boost?
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Qw3r7yU10p!
Qw3r7yU10p!
boost is a growing set of libraries for c++ written by many people and used by even more. It was started by Josuttis who is the guy who designed the STL. Some of the library will likely be standardised into future versions of c++. I think tuples are going to be in for example. It's good stuff.

pete

[edited by - petewood on July 17, 2003 7:21:01 PM]
risingdragon3
risingdragon3
Boost::function is already in as well as a ton of others. I forget exactly but I''m sure cuj will have an article up about the new standardized stuff.
Much of boost is written by people who are on the committee and such. It''ll give your compiler a workout though
Ishan
Ishan
This is definitely possible within C++ syntax. Here you go:


#include <iostream>
#include <string>
using namespace std;

template<class T>
class functor{
public:
functor(void (T::*iptr)(),T * ithat){
member_ptr = iptr;
that = ithat;
}
void (T::*member_ptr)(void);
T * that;

void execute(){
(that->*member_ptr)();
}
};

class foo{
public:
void func(){
cout << "hello world" << endl;
}
};

void main(){
foo b;

functor<foo> f(foo::func,&b);
f.execute();
}


There are really two tricks here...the first is that you need to use the magical syntax to pass and store pointers to member functions, which can be found in the functor constructor and the declaration of member_ptr. Second, in order to call the function, you need to simply deference the function pointer and pass it to the arrow operator.

Let me know if you have any more questions.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.