Solved

Pointer to methods

Posted on 2002-07-08
8
228 Views
Last Modified: 2010-04-01
Please, can anyone point me where can I find material about how do something like:

Object *pObject = new Object();

//This funcion store it in a proprietary table
pointer_store(pObject, &pObject->methodA())
{
...
}

//Execute from its table
exec_stored_pointer()
{
...
}
0
Comment
Question by:Korck
  • 3
  • 3
  • 2
8 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 7139260
You normally can't just directly jump to a method... the compiler has to set up the 'this' pointer.

There are several ways to do it, but the correct way FOR YOU will depend upon what you need to do.  Here is the summary:

1) You can save and excute a function that is a static member.  So when you declare the member function in the object header, use the keyword static (that causes some related problems in that a static member function can access only other static member functions and variables).

2) You can save the object pointer and use that to 'get into the object'

    //Execute from its table
    exec_stored_pointer() {
        pTheObject->(*pfnPonterThatWasStored)();
    }

3) You can 'be in the object' when you call the ptr to the stored fn:

CMyClass::DoThatThing( int nThingToDO )
{
    if (nTHingToDo==1) {
        int nRet= (*pFnThingToDoNumber1)();
    }
}

I will explain in detail if you will take a moment to describe the situation in which you will be using this technique.

-- Dan
0
 
LVL 30

Accepted Solution

by:
Axter earned 50 total points
ID: 7139411
The following method only works if all your methods have the same DEFAULT arguments.

#include <vector>
#include <algorithm>

#include <string> //Needed for example code
#include <iostream> //Needed for example code



class FunctionPointerBase
{
public:
     virtual void PerformFunction() = 0;
     virtual ~FunctionPointerBase(){}
};

template<typename T_obj, typename T_fx>
class FunctionPointer : public FunctionPointerBase
{
public:
    typedef T_fx T_func;
     FunctionPointer(T_obj &Obj, T_func Func): m_Obj(Obj), m_Func(Func){}
     virtual void PerformFunction()
     {
          (m_Obj.*m_Func)();
     }
     T_func m_Func;
     T_obj &m_Obj;
};

class DeleteObject
{
public:
     template<typename T>
          operator()(T& ptr)
     {
          delete &*ptr;
          ptr = NULL;
          return true;
     }
};

class FunctionPointerStore
{
public:
     template<typename T_obj, typename T_func>
     void pointer_store(T_obj &Obj, T_func Func)
     {
          Store.push_back(new FunctionPointer<T_obj,T_func>(Obj, Func));
     }
     void exec_stored_pointer(int Index)
     {
          Store[Index]->PerformFunction();
     }
     int GetSize() {return Store.size();}
     ~FunctionPointerStore()
     {
          Store.erase(std::remove_if(Store.begin(), Store.end(),DeleteObject()), Store.end());
     }
private:
     std::vector<FunctionPointerBase*> Store;
};

//Example classes
class foo
{
public:
     void SomeFunction()
     {
          std::cout << "foo" << std::endl;
     }
};

class foo2
{
public:
     void Xyz(void)
     {
          std::cout << "foo2" << std::endl;
     }
};

class wiget
{
public:
     void AnotherFuction(int x = 3)
     {
          std::cout << "wiget " << x  << std::endl;
     }
};

class wiget2
{
public:
     void Abc(std::string Data = "abc")
     {
          std::cout << "wiget2 " << Data << std::endl;
     }
};

//Example usage
int main(int argc, char* argv[])
{
     FunctionPointerStore My_FunctionPointerStore;
     foo My_foo;
     My_FunctionPointerStore.pointer_store(My_foo, foo::SomeFunction);
     wiget My_wiget;
     My_FunctionPointerStore.pointer_store(My_wiget, wiget::AnotherFuction);
     foo2 My_foo2;
     My_FunctionPointerStore.pointer_store(My_foo2, foo2::Xyz);
     wiget2 My_wiget2;
     My_FunctionPointerStore.pointer_store(My_wiget2, wiget2::Abc);
     My_FunctionPointerStore.exec_stored_pointer(0);
     My_FunctionPointerStore.exec_stored_pointer(1);
     My_FunctionPointerStore.exec_stored_pointer(2);
     My_FunctionPointerStore.exec_stored_pointer(3);
     return 0;
}
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7139446
Axter, It seems to me that that is a complicated way using my option #2.  If you have the object and a pointer to a function in that object, then you can call that function.

-- Dan

0
VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

 
LVL 30

Expert Comment

by:Axter
ID: 7139456
>>Axter, It seems to me that that is a complicated way
>>using my option #2.  If you have the object and a
>>pointer to a function in that object, then you can call
>>that function.

That's because they're not the same thing.
Your option #2 works if all the objects are of the same type.  But will not work if objects of different types and different base types are being used.

In re-reading the question, your option #2 might be what the questioner is asking for.

When I first read it I thought the questioner is asking about storing different type objects.

Korck,
Are all the objects of the same type?
0
 

Author Comment

by:Korck
ID: 7139501
No...

I'm dooing a  configurable generic message dispatcher, so to do my events "configurable", I must be abble to unknow the method's object type.... and I don't want to allow only static methods and global functions.



0
 
LVL 30

Expert Comment

by:Axter
ID: 7139538
>>I'm dooing a  configurable generic message dispatcher,
>>so to do my events "configurable", I must be abble to
>>unknow the method's object type.... and I don't want to
>>allow only static methods and global functions.

So then the example I posted is inline with what you need.

Have you tried it out?
Do you understand it?
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7139768
>>I must be abble to unknow the method's object type....

I think you mean that when you call the function, you won't know what type of object you are calling.  It looks like Axter's code saves both an object reference and a pointer to a member function for that object.  So it will do the job.    

Of course the object must continue to exist from the time you save it to the time you use it's function.

MFC's message dispatcher uses a set of macros to build a similar table.  Another technique is to derive all of the objects from a particular base class and have the dispatch handler be a virutal function.

-- Dan
0
 

Author Comment

by:Korck
ID: 7141586
Yes, that´s it Axter.

Thank you all in advance :)

0

Featured Post

ScreenConnect 6.0 Free Trial

Want empowering updates? You're in the right place! Discover new features in ScreenConnect 6.0, based on partner feedback, to keep you business operating smoothly and optimally (the way it should be). Explore all of the extras and enhancements for yourself!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
TCP/IP Socket - connection close results in data lost 14 136
Socket Programming (Unix) 8 129
I could not build boost code, 10 88
c++, dynamic object by json 1 42
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question