PDA

View Full Version : Pointers to Functions of a Class



2
03-21-2001, 08:54 AM
Hi. I'm trying to do something a little complicated. I'm trying to create a pointer to a virtual function in an instance of a class I created, which isn't of the baseclass type. Ideally, the function pointer should link to the derrived class's function.
In code...

class CBaseClass
{
public:
virtual void Function( void );
};

class CDerrivedClass : public CBaseClass
{
public:
void Function( void ) { }
};

CBaseClass *object;

//Pretend we're in a GLOBAL function, and everything has been initialized...

void (* Func)( void ) = object->Function;

/*This will generate the error (in MSVC++ 6.0)...

"Cannot convert parameter 1 from 'void (void)' to 'void (__cdecl *)(void)"

And I don't know how to fix this. Any help would be greatly appreciated. Thanks a bunch! (Oh and typecasting doesn't work...)*/

DFrey
03-21-2001, 09:17 AM
Think along the lines of static member functions.

2
03-21-2001, 09:39 AM
Doh!

I tried doing "static virtual" and got an error for that. But I guess if I just take out the virtual and throw in an empty function it works. Thanks!

[This message has been edited by 2 (edited 03-21-2001).]

davepermen
03-21-2001, 11:17 AM
hm.. class functions are at standart __thiscall defined, normal functions __cdecl

the calling convention for those are different, ( one time it has to push the thispointer, too, the other time there is no thispointer )

like that those functions are different in assembler, and like that you have to do a typeconversion http://www.opengl.org/discussion_boards/ubb/smile.gif

(dont try to use __thispointer ( or is it __thiscall, dont remember.. ), cause its not allowed in visual c, one of the "bugs" of microsoft products..)

you can possibly write

virtual void __cdecl Function( void );

possibly not.. http://www.opengl.org/discussion_boards/ubb/smile.gif

other types are __fastcall, where no pushpops are done ( faster, but no ",..." possible )

and there is __declspec( naked )

wich creates a function with nothing in ( in assembler )

and you then have to write the whole bunch yourselfs ( with __asm{ }, never forget the 'ret' at the end! else it runs and runs and runs aaaaaaaaaaaaaaaaaaaaaaaaaaand

crashes

)

have a nice day today, perhaps its your last

hm.. i have a bad day today, i'm always sarkastik and talk with myself in forums.. heeeeelp me, i need my visual c back!

MikeC
03-21-2001, 01:33 PM
Well, static member functions can't be virtual, since obviously there's no object to get a vtable pointer from.

A pointer to a nonstatic member function which looks like this:

void MyClass::myFunc(void)

needs the following typedef:

typedef void(MyClass::*myFuncPtr)(void)

Remember that this is a fundamentally different type than void(*myFunc)(void); you can't pass one to a function expecting the other. I'm a bit confused as to why you don't just pass a pointer to the object instead and call the virtual method on it. That's what virtual functions are for, after all.

Xor
03-21-2001, 02:51 PM
You know, the power of OpenGL is in C++. Well organized and disigned OO programm could totally utilize OGL. So add any C++ forum to your list also :)

Gorg
03-21-2001, 02:54 PM
Not True. static member can be almost virtual with something called a template method.

in your base class :


class A
{
public:
static void dosomething(const A& a)
{
a.virtualDo();
}

protected:
virtual void virtualDo() = 0;
}

in your derived classes, you simple overide virtual do.


[This message has been edited by Gorg (edited 03-21-2001).]

MikeC
03-21-2001, 03:52 PM
Well yes, but then what's the point? You can't pass a pointer to the static memfun in your example as a callback, because the library/framework which is making the callback (presumably a C API if you can't pass pointers to member functions) doesn't know what object to pass it. If it _is_ a C++ API and it _does_ know the object, why isn't it calling a virtual function directly?

I've used that technique once or twice (mainly for a Win32 message handler where the window wrapper object can be retrieved from the HWND in the message), but in most cases it just seems to obfuscate things for no reason.

Incidentally, your example isn't going to compile, because you call virtualDo() on a const reference but virtualDo() isn't declared const. (I know, I know, this is way off topic.)

bobrien
03-21-2001, 09:23 PM
Sorry I didn't read the whole thread but...
Don't you usually keep a pointer to an instance of the class and then call the methods (virtual or otherwise) by pointer.
ie.

x *p; // Set some were valid at an appropriate time.

p->method();

Michail Bespalov
03-21-2001, 11:49 PM
Hi

2,if I understand you right

class CA{
public:
virtual void f1(){
printf("CA::f1\n");
}
virtual void f2(){
printf("CA::f2\n");
}
virtual void f3(){
printf("CA::f3\n");
}
};

typedef void(CA::*PTR)();

void main(){
CA *ca=new CA;

PTR p1=ca->f1;
PTR p2=ca->f2;
PTR p3=ca->f3;

(ca->*p1)();
(ca->*p2)();
(ca->*p3)();

delete ca;
}

result :
CA::f1
CA::f2
CA::f3