Function pointer to "member" function

Discussion in 'C++' started by Kasper Middelboe Petersen, Jun 4, 2011.

  1. Lets say I have these 3 classes:

    Class Parent {};
    Class Child : public Parent {};
    Class Priest {};

    Since it is a library I'm creating the following two problems arise:
    1. I have no control over what the name of "Priest" as this is up to
    the person using the library in the first place to create - and he
    needs more than one different class extending Parent at the same time.
    2. I need Child to pass one or more callback functions on to Priest
    which allows it to access Child's private parts!

    This is what I've come up with so far and it seems to work:

    class Child : public Parent {
    public:
    Child() : priest(callbackfunc, this) {};

    static void callbackfunc(Parent* p) {
    std::cout << "Mmm... Private " << (Child*)p->parts << std::endl;
    };

    void run() {
    priest.grab();
    };

    private:
    Priest priest;
    int parts;
    };

    class Priest {
    public:
    Priest(void (*_callbackfunc)(Parent*), Parent *_p)
    : callbackfunc(_callbackfunc), p(_p) {};

    void grab() {
    (*callbackfunc)(p);
    };

    private:
    void (*callbackfunc)(Parent*);
    Parent* p;
    };


    But I'm not sure if this is the correct way to solve this or if there
    is a better/cleaner one?


    Thanks,
    Kasper
     
    Kasper Middelboe Petersen, Jun 4, 2011
    #1
    1. Advertising

  2. Great - a typo.

    In requirement 1; I have no control over the name Child ofcause - I do
    have over Priest (and Parent).


    /Kasper

    On Jun 4, 3:21 pm, Kasper Middelboe Petersen <>
    wrote:
    > Lets say I have these 3 classes:
    >
    > Class Parent {};
    > Class Child : public Parent {};
    > Class Priest {};
    >
    > Since it is a library I'm creating the following two problems arise:
    > 1. I have no control over what the name of "Priest" as this is up to
    > the person using the library in the first place to create - and he
    > needs more than one different class extending Parent at the same time.
    > 2. I need Child to pass one or more callback functions on to Priest
    > which allows it to access Child's private parts!
    >
    > This is what I've come up with so far and it seems to work:
    >
    > class Child : public Parent {
    > public:
    >   Child() : priest(callbackfunc, this) {};
    >
    >   static void callbackfunc(Parent* p) {
    >     std::cout << "Mmm... Private " << (Child*)p->parts << std::endl;
    >   };
    >
    >   void run() {
    >     priest.grab();
    >   };
    >
    > private:
    >   Priest priest;
    >   int parts;
    >
    > };
    >
    > class Priest {
    > public:
    >   Priest(void (*_callbackfunc)(Parent*), Parent *_p)
    >     : callbackfunc(_callbackfunc), p(_p) {};
    >
    >   void grab() {
    >     (*callbackfunc)(p);
    >   };
    >
    > private:
    >   void (*callbackfunc)(Parent*);
    >   Parent* p;
    >
    > };
    >
    > But I'm not sure if this is the correct way to solve this or if there
    > is a better/cleaner one?
    >
    > Thanks,
    > Kasper
     
    Kasper Middelboe Petersen, Jun 4, 2011
    #2
    1. Advertising

  3. Kasper Middelboe Petersen

    Rune Allnor Guest

    On Jun 4, 3:21 pm, Kasper Middelboe Petersen <>
    wrote:
    > Lets say I have these 3 classes:
    >
    > Class Parent {};
    > Class Child : public Parent {};
    > Class Priest {};
    >
    > Since it is a library I'm creating the following two problems arise:
    > 1. I have no control over what the name of "Priest" as this is up to
    > the person using the library in the first place to create - and he
    > needs more than one different class extending Parent at the same time.
    > 2. I need Child to pass one or more callback functions on to Priest
    > which allows it to access Child's private parts!


    Have you considered to use the visitor pattern?

    Rune
     
    Rune Allnor, Jun 6, 2011
    #3
  4. Kasper Middelboe Petersen

    Werner Guest

    On Jun 4, 3:21 pm, Kasper Middelboe Petersen <>
    wrote:
    > Lets say I have these 3 classes:
    >
    > Class Parent {};
    > Class Child : public Parent {};
    > Class Priest {};
    >
    > Since it is a library I'm creating the following two problems arise:
    > 1. I have no control over what the name of "Priest" as this is up to
    > the person using the library in the first place to create - and he
    > needs more than one different class extending Parent at the same time.


    The code below that "seems to work" suggests otherwise. Why,
    you are using the word Priest in the definition of Child? So how
    can you use this name if you have no control over what it will be...


    > 2. I need Child to pass one or more callback functions on to Priest
    > which allows it to access Child's private parts!


    I'm not sure what you want, but a member function pointer
    looks like this:

    class Child
    {
    private:
    void someMember( int );
    };

    typedef void (Child::*childCallback)( int );

    Combined with an instance to Child, you would be able
    to call someMember:

    void indirectCall( Child& theChild, childCallback f, int arg )
    {
    (theChild.*f)( arg );
    }

    You could always look at something like boost::function to
    create "handles" to private callbacks.

    Alternatively:

    You could provide an interface that the
    client can use to notify Child. You then need to anticipate
    roles that might influence child's behaviour, and define
    interfaces with whom these "roles" associate.

    e.g: Priest relates to Christian, perhaps...

    struct Christian
    {
    virtual void baptise() = 0;
    protected:
    ~Christian(){}
    };

    class Child : public Christian
    {
    private:
    virtual void baptise() = 0;
    };

    The client can then access child's internals by
    having a relationship with the applicable role...

    I consider this better (more clarity) than callbacks...

    Kind regards,

    Werner
     
    Werner, Jun 6, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Newsgroup - Ann
    Replies:
    5
    Views:
    610
    John Carson
    Jul 30, 2003
  2. Fraser Ross
    Replies:
    4
    Views:
    1,052
    Fraser Ross
    Aug 14, 2004
  3. Stephen Howe
    Replies:
    2
    Views:
    290
    Stephen Howe
    Nov 6, 2012
  4. somenath
    Replies:
    10
    Views:
    283
    James Kanze
    Jul 2, 2013
  5. somenath
    Replies:
    2
    Views:
    160
    somenath
    Aug 29, 2013
Loading...

Share This Page