Calling C++ member functions through pointers

Started by
15 comments, last by BS-er 21 years, 1 month ago
What I would like to do is make a template class that can be set up to call some basic set/get member functions of the input class type. This would be for setting and getting properties. For example a class has a bunch of set and get functions for floats, ints, vectors, quaternions and other common types. What I want this template class to do is assist in setting and getting member values via a text string argument. So if my template class is called "PropertyInterface", instantiation of my template would be something like:
            
PropertyInterface<CMyClass> TheClassInterface;
     
And this interface class can be configured after instantiation as follows:
                       
TheClassInterface.RegisterFloatInterface("MaxSpeed", CMyClass::GetMaxSpeed, CMyClass::SetMaxSpeed);
  
given the function prototypes:
  
float CMyClass::GetMaxSpeed();
void CMyClass::SetmaxSpeed(Float);
  
Maybe instead of RegisterFloatInterface, a general function could be overloaded such that you need not specify "Float" in the function name. So through this interface class you would set and get values using text names, maybe like the following:
                     
TheClassInterface.SetCurrentInstance(&m_MyClassInstance);
TheClassInterface.Set("MaxSpeed", 30.0f);
    
Basically I'm asking for some tips on handling pointers to member functions to make something like this work in a template class. Specifically, how do you define their types, and how do you call them?. It may even need to deal with inheritance, i.e. set and get functions of the ancestor classes of CMyClass. Value of good ideas: 10 cents per dozen. Implementation of the good ideas: Priceless. Proxima Rebellion - A 3D action sim with a hint of strategy [edited by - BS-er on March 2, 2003 11:27:37 AM]
Value of good ideas: 10 cents per dozen.Implementation of the good ideas: Priceless.Machines, Anarchy and Destruction - A 3D action sim with a hint of strategy
Advertisement
If you want to use a string to tell it what property to set, then you need to use a soft-architecture and store the values in an associative container (like a map).

Then you just need to add a get & set method to access data in the container.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Thanks for your reply, but I''m not sure I''m any closer. I want to be able to take any existing class that has these set and get functions for certain data types, and create one interface class instance that can initialize one or all of them (by passing it pointers to the class instances). There would be no modifying the existing class.

I would use an associative container, but it would be to access the function pointer. I think I have the general approach decided, but I never seem to find good documentation on pointers to C++ member functions, and how to type, declare and use them.

Value of good ideas: 10 cents per dozen.
Implementation of the good ideas: Priceless.
Proxima Rebellion - A 3D action sim with a hint of strategy
Value of good ideas: 10 cents per dozen.Implementation of the good ideas: Priceless.Machines, Anarchy and Destruction - A 3D action sim with a hint of strategy
Well some more searching may have dug up a good link: http://www.function-pointer.org . I''ll go with it for now and see how far it takes me.

Value of good ideas: 10 cents per dozen.
Implementation of the good ideas: Priceless.
Proxima Rebellion - A 3D action sim with a hint of strategy
Value of good ideas: 10 cents per dozen.Implementation of the good ideas: Priceless.Machines, Anarchy and Destruction - A 3D action sim with a hint of strategy
If you want to use a string to tell it what property to set, then you need to use a soft-architecture and store the values in an associative container (like a map).

Then you just need to add a get & set method to access data in the container.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
quote:Original post by Magmai Kai Holmlor
[...] you need to use a soft-architecture [...]

Soft-architecture? Have you just made that up? The only meaning I can find for it would not make sense in the used context.
quote:
[...] store the values in an associative container (like a map).

Consider the following function signatures...

  void CMyClass::SetSomeValue(float);void CMyClass::SetSomeOtherValue(int);float CMyClass::GetSomeValue() const;int CMyClass::GetSomeOtherValue() const;  

How do you propose to store pointers to those types in a single map? How would you package the function arguments and return values in a manner that avoids loss of information or of type-safety?
quote:
Then you just need to add a get & set method to access data in the container.

That wouldn''t solve what he''s trying to do, which isn''t possible without either escaping C++''s type-system and then writing (or otherwise obtaining) the code to implement a dynamic type-system, or creating a ridiculously convoluted template solution that would do well as the subject of a Ph.D. paper. There might be a more C++ like way of doing what BS-er wants, but that depends on what problem he''s actually trying to solve, which isn''t apparent.
I'm doing this right now.
Compiletime it's just a matter of template meta-programming, so that the overhead is nil - same as an straight assign / function call.
In Runtime, it's more interesting. You can use templates that take any times for any number of arguments up to a predefined level, then, when it is instantiated, check the type ID of that type to the type ID exposed in the property definition...
Yep.
That's what'll I do (I've been stuck on this since sunday)
..
This is what my code looks like right now (Compiletime only):

    struct vertex_b {	float pos[3];		void rotate(float);};namespace VertexProp {	GDN_DEFINE_PROPERTY(x)	GDN_DEFINE_PROPERTY(y)	GDN_DEFINE_PROPERTY(z)	GDN_DEFINE_PROPERTY(Rotate)}template <> struct MetaClass<vertex_b> {	typedef Implements<		VertexProp::x, MemberArray<vertex_b,float,&vertex_b::pos,0>,		VertexProp::y, MemberArray<vertex_b,float,&vertex_b::pos,1>,		VertexProp::z, MemberArray<vertex_b,float,&vertex_b::pos,2>,VertexProp::Rotate,Function1<void,vertex_b,float,&vertex_b::rotate>	> Implemented;};typedef Interface<	VertexProp::x,float,	VertexProp::y,float,	VertexProp::z,float,VertexProp::Rotate,Function<void,float>> VertexIntf;		vertex_b obj;BindToClass<VertexIntf,vertex_b> vertex(obj);cout << "("<< vertex.x.Get() << "," << vertex.y.Get() << "," << vertex.z.Get() << ")";	vertex.rotate(12);//..and to comeBindToClassRT<VertexIntf,vertex_b> vertexRT(obj);vertexRT["x"] = 12.23;vertexRT["y"] = 23.45;vertexRT["Rotate"](123.45);    


There are more stuff, like member get/set pairs, read only properties; the function system works polymorphically.
Properties can have different get / set type signitures. And so on. There is a list, I haven't got around to finishing the features list yet

(I hear the flames already....)
*500

EDIT: And, you can do proper Interface MI (java style MI) with the Property::Inherits property

-----------------------------
Gamedev for learning.
libGDN for putting it all together.

[edited by - risingdragon3 on March 3, 2003 4:52:48 PM]
this question triggers my interest - i am wondering something similar.

I''m looking at SDL wondering if it would be possible for me to add multithreading functionality.


  class clientController{private:   int updateThread(void *unused){      //blah   }   SDL_Thread *thread;public:	clientController(CConnection *con, linklist *others ){                //blah	        thread = SDL_CreateThread(updateThread, NULL);	}  //blah}--------------------Configuration: Server - Win32 Release--------------------Compiling...mainbrum.cppC:\programming\0-JETTHUNDER\ChatServer\clientController.h(64) : error C2664: ''SDL_CreateThread'' : cannot convert parameter 1 from ''int (void *)'' to ''int (__cdecl *)(void *)''        None of the functions with this name in scope match the target type  


sadly this doesnt work. If it did, the creator would create a thread and it would run happily along. anybody know how to make it work???
I've thought about this one as well, After about a week, i came up with a lot of template and inherited classes and it really wasnt as good as what i wanted so i through it out. It's pretty dirty, especially trying to get it to be scalable for more than just getters and setters, or a predefined number and type of argument and written in such a way that modification to the existing frame work to support methods with different types and number of parameters would be minimiazed. If anybody has a good solution, please post. I think Corba has a implementation respository where classes can register their methods through interfaces and others can look up into this repository for to access methods (not sure as i have never used this feature of Corba)

[edited by - _walrus on March 3, 2003 5:09:27 PM]
Sounds a bit like a remote procedure call to me. Don''t know if you need the templates however.....

To set up pointers to member functions you can do something like...

class base; // Forward Dec

typedef float (base::*GFPTR)(void); // Pointer to a member function returning float, no parameters
typedef void (base::*SFPTR)(float); // Pointer to a member function returning void, taking float

The class base can then provide the registration for the methods

void base::Register( const char* _name, SFPTR _set, GFPTR _get )
{
// Save in some database here
}

You can then derive from the class base to provide the set/get methods you need

class derived : public base
{
public:
float GetSpeed( ) const;
void SetSpeed( float );
};

Then you can register with something like

void derived::RegisterInterfaces( void )
{
base::Register("Speed", &GetSpeed, &SetSpeed);
}

Ciao

This topic is closed to new replies.

Advertisement