Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 235
  • Last Modified:

Pointer to methods

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
Korck
Asked:
Korck
  • 3
  • 3
  • 2
1 Solution
 
DanRollinsCommented:
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
 
AxterCommented:
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
 
DanRollinsCommented:
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
AxterCommented:
>>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
 
KorckAuthor Commented:
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
 
AxterCommented:
>>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
 
DanRollinsCommented:
>>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
 
KorckAuthor Commented:
Yes, that´s it Axter.

Thank you all in advance :)

0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now