Delegation question...

Discussion in 'C++' started by barcaroller, May 23, 2008.

  1. barcaroller

    barcaroller Guest

    What is the common way/design-pattern (if any) in C++ for delegating
    function calls that are not handled by a certain class. Public
    inheritance would be one way but not all classes are meant to inherit
    from (e.g. STL).


    Example:

    class A
    {
    public:
    foo();

    private:
    set<string> myset;
    }

    A myObj;
    myObj.insert(); // compiler error of course


    Is there some mechanism (direct or indirect) where a function that is
    not handled by myObj gets delegated to another object (e.g. myset)?
     
    barcaroller, May 23, 2008
    #1
    1. Advertising

  2. barcaroller

    Daniel Pitts Guest

    barcaroller wrote:
    > What is the common way/design-pattern (if any) in C++ for delegating
    > function calls that are not handled by a certain class. Public
    > inheritance would be one way but not all classes are meant to inherit
    > from (e.g. STL).
    >
    >
    > Example:
    >
    > class A
    > {
    > public:
    > foo();
    >
    > private:
    > set<string> myset;
    > }
    >
    > A myObj;
    > myObj.insert(); // compiler error of course
    >
    >
    > Is there some mechanism (direct or indirect) where a function that is
    > not handled by myObj gets delegated to another object (e.g. myset)?


    I believe you can add the following to your class:
    set<string> &operator->() { return myset; }

    and then you can do myObj->insert()
    Although, this seems a bit troublesome.

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
     
    Daniel Pitts, May 23, 2008
    #2
    1. Advertising

  3. barcaroller

    Ian Collins Guest

    barcaroller wrote:
    > What is the common way/design-pattern (if any) in C++ for delegating
    > function calls that are not handled by a certain class. Public
    > inheritance would be one way but not all classes are meant to inherit
    > from (e.g. STL).
    >
    >
    > Example:
    >
    > class A
    > {
    > public:
    > foo();
    >
    > private:
    > set<string> myset;
    > }
    >
    > A myObj;
    > myObj.insert(); // compiler error of course
    >
    >
    > Is there some mechanism (direct or indirect) where a function that is
    > not handled by myObj gets delegated to another object (e.g. myset)?


    No, C++ does not support this form of delegation.

    --
    Ian Collins.
     
    Ian Collins, May 23, 2008
    #3
  4. barcaroller

    James Kanze Guest

    On 24 mai, 00:43, Ian Collins <> wrote:
    > barcaroller wrote:
    > > What is the common way/design-pattern (if any) in C++ for delegating
    > > function calls that are not handled by a certain class. Public
    > > inheritance would be one way but not all classes are meant to inherit
    > > from (e.g. STL).


    > > Example:


    > > class A
    > > {
    > > public:
    > > foo();
    > > private:
    > > set<string> myset;
    > > }


    > > A myObj;
    > > myObj.insert(); // compiler error of course


    > > Is there some mechanism (direct or indirect) where a function that is
    > > not handled by myObj gets delegated to another object (e.g. myset)?


    > No, C++ does not support this form of delegation.


    Not directly. The closest you can come, I think, is to use
    private inheritance and using declarations.

    Note that this type of delegation is effectively exposing part
    of your internals, to some degree. Although significantly
    wordier, I rather favor being explicit in forwarding, so that
    the complete interface of the object isn't available. Most of
    the time, at least; I also have at least one case where the
    non-mutable interface of the object is exactly that of
    std::vector< std::string > and I can conceive of others. Which
    means that I do have to duplicate a lot (including things like
    typedef's). But it's not 100% duplication either; I have
    iterator typedefed to std::vector<std::string>::const_iterator,
    for example.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 24, 2008
    #4
  5. On 2008-05-23 23:58, barcaroller wrote:
    > What is the common way/design-pattern (if any) in C++ for delegating
    > function calls that are not handled by a certain class. Public
    > inheritance would be one way but not all classes are meant to inherit
    > from (e.g. STL).
    >
    >
    > Example:
    >
    > class A
    > {
    > public:
    > foo();
    >
    > private:
    > set<string> myset;
    > }
    >
    > A myObj;
    > myObj.insert(); // compiler error of course
    >
    >
    > Is there some mechanism (direct or indirect) where a function that is
    > not handled by myObj gets delegated to another object (e.g. myset)?


    Private inheritance is one way to do it:

    #include <iostream>

    class Foo
    {
    public:
    void print() { std::cout << "Foo\n"; }
    };

    class Bar : private Foo
    {
    public:
    using Foo::print;
    };

    int main()
    {
    Bar b;
    b.print();
    }

    But most often I would recommend to manually do the delegation:

    #include <iostream>

    class Foo
    {
    public:
    void print() { std::cout << "Foo\n"; }
    };

    class Bar
    {
    Foo f;
    public:
    void print() { f.print(); }
    };

    int main()
    {
    Bar b;
    b.print();
    }

    --
    Erik Wikström
     
    Erik Wikström, May 24, 2008
    #5
  6. barcaroller

    Ian Collins Guest

    James Kanze wrote:
    > On 24 mai, 00:43, Ian Collins <> wrote:
    >> barcaroller wrote:
    >>> What is the common way/design-pattern (if any) in C++ for delegating
    >>> function calls that are not handled by a certain class. Public
    >>> inheritance would be one way but not all classes are meant to inherit
    >>> from (e.g. STL).

    >
    >>> Example:

    >
    >>> class A
    >>> {
    >>> public:
    >>> foo();
    >>> private:
    >>> set<string> myset;
    >>> }

    >
    >>> A myObj;
    >>> myObj.insert(); // compiler error of course

    >
    >>> Is there some mechanism (direct or indirect) where a function that is
    >>> not handled by myObj gets delegated to another object (e.g. myset)?

    >
    >> No, C++ does not support this form of delegation.

    >
    > Not directly. The closest you can come, I think, is to use
    > private inheritance and using declarations.
    >

    I was going to suggest that technique, but decided against it as the OP
    wanted to delegate members of std::set. I wouldn't recommend deriving
    from a standard container.

    --
    Ian Collins.
     
    Ian Collins, May 24, 2008
    #6
  7. barcaroller

    James Kanze Guest

    On May 24, 9:47 am, Ian Collins <> wrote:

    [...]
    > I was going to suggest that technique, but decided against it as the OP
    > wanted to delegate members of std::set. I wouldn't recommend deriving
    > from a standard container.


    Not even privately? I have no problems with private inheritance
    from a standard container; private inheritance is part of the
    implementation.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 24, 2008
    #7
  8. barcaroller

    Ian Collins Guest

    James Kanze wrote:
    > On May 24, 9:47 am, Ian Collins <> wrote:
    >
    > [...]
    >> I was going to suggest that technique, but decided against it as the OP
    >> wanted to delegate members of std::set. I wouldn't recommend deriving
    >> from a standard container.

    >
    > Not even privately? I have no problems with private inheritance
    > from a standard container; private inheritance is part of the
    > implementation.
    >

    Yes, you're right, I overlooked private inheritance.

    --
    Ian Collins.
     
    Ian Collins, May 24, 2008
    #8
  9. barcaroller

    tedzhou Guest

    On May 24, 5:19 pm, Ian Collins <> wrote:
    > James Kanze wrote:
    > > On May 24, 9:47 am, Ian Collins <> wrote:

    >
    > >     [...]
    > >> I was going to suggest that technique, but decided against it as the OP
    > >> wanted to delegate members of std::set.  I wouldn't recommend deriving
    > >> from a standard container.

    >
    > > Not even privately?  I have no problems with private inheritance
    > > from a standard container; private inheritance is part of the
    > > implementation.

    >
    > Yes, you're right, I overlooked private inheritance.


    Private inheritance is not suggested on standard container either.
    Because the standard containers are not designed for inheritance at
    all.
    Just think about the polymorphism and virtual destruction , then
    you'll
    get the conclusion that inheritance from standard containors will be
    dangerous.
     
    tedzhou, May 26, 2008
    #9
  10. barcaroller

    Ian Collins Guest

    tedzhou wrote:
    > On May 24, 5:19 pm, Ian Collins <> wrote:
    >> James Kanze wrote:
    >>> On May 24, 9:47 am, Ian Collins <> wrote:
    >>> [...]
    >>>> I was going to suggest that technique, but decided against it as the OP
    >>>> wanted to delegate members of std::set. I wouldn't recommend deriving
    >>>> from a standard container.
    >>> Not even privately? I have no problems with private inheritance
    >>> from a standard container; private inheritance is part of the
    >>> implementation.

    >> Yes, you're right, I overlooked private inheritance.

    >
    > Private inheritance is not suggested on standard container either.
    > Because the standard containers are not designed for inheritance at
    > all.
    > Just think about the polymorphism and virtual destruction , then
    > you'll
    > get the conclusion that inheritance from standard containors will be
    > dangerous.


    With public inheritance maybe, but you can't point a base* to a derived
    object if derived uses private inheritance. Private inheritance hides
    the fact that a derived is a base. Try

    class base {};
    class derived : base {};

    base* p = new derived;

    --
    Ian Collins.
     
    Ian Collins, May 26, 2008
    #10
  11. barcaroller

    red floyd Guest

    tedzhou wrote:
    > On May 24, 5:19 pm, Ian Collins <> wrote:
    >> James Kanze wrote:
    >>> On May 24, 9:47 am, Ian Collins <> wrote:
    >>> [...]
    >>>> I was going to suggest that technique, but decided against it as the OP
    >>>> wanted to delegate members of std::set. I wouldn't recommend deriving
    >>>> from a standard container.
    >>> Not even privately? I have no problems with private inheritance
    >>> from a standard container; private inheritance is part of the
    >>> implementation.

    >> Yes, you're right, I overlooked private inheritance.

    >
    > Private inheritance is not suggested on standard container either.
    > Because the standard containers are not designed for inheritance at
    > all.


    Not necessarily. Several of the standard adapter classes
    (std::priority_queue for example) have protected members, which implies
    that they were designed to be inherited from.
     
    red floyd, May 26, 2008
    #11
  12. barcaroller

    Kai-Uwe Bux Guest

    tedzhou wrote:

    > On May 24, 5:19 pm, Ian Collins <> wrote:
    >> James Kanze wrote:
    >> > On May 24, 9:47 am, Ian Collins <> wrote:

    >>
    >> > [...]
    >> >> I was going to suggest that technique, but decided against it as the
    >> >> OP wanted to delegate members of std::set.  I wouldn't recommend
    >> >> deriving from a standard container.

    >>
    >> > Not even privately?  I have no problems with private inheritance
    >> > from a standard container; private inheritance is part of the
    >> > implementation.

    >>
    >> Yes, you're right, I overlooked private inheritance.

    >
    > Private inheritance is not suggested on standard container either.
    > Because the standard containers are not designed for inheritance at
    > all.
    > Just think about the polymorphism and virtual destruction , then
    > you'll
    > get the conclusion that inheritance from standard containors will be
    > dangerous.


    That argument is bogus for two reasons:

    (a) As others have pointed out, private differs from public inheritance with
    regard to destruction.

    (b) Even with public inheritance, the argument does not hold as it would
    apply equally well to std::unary_function or std::iterator, two classes
    that are meant to be publicly inherited from and that lack virtual
    destructors. Inheritance in C++ is not necessarily tied to polymorphism.

    [Note: that you failed to point out a valid reason as to why public
    inheritance from standard containers might not be such a good move, is not
    to say that there are no such reasons. However, those tend to focus on
    other issues rather than the lack of a virtual destructor.]


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, May 26, 2008
    #12
  13. barcaroller

    James Kanze Guest

    On May 26, 11:00 am, Ian Collins <> wrote:
    > tedzhou wrote:
    > > On May 24, 5:19 pm, Ian Collins <> wrote:
    > >> James Kanze wrote:
    > >>> On May 24, 9:47 am, Ian Collins <> wrote:
    > >>> [...]
    > >>>> I was going to suggest that technique, but decided against it as the OP
    > >>>> wanted to delegate members of std::set. I wouldn't recommend deriving
    > >>>> from a standard container.
    > >>> Not even privately? I have no problems with private inheritance
    > >>> from a standard container; private inheritance is part of the
    > >>> implementation.
    > >> Yes, you're right, I overlooked private inheritance.


    > > Private inheritance is not suggested on standard container
    > > either. Because the standard containers are not designed
    > > for inheritance at all. Just think about the polymorphism
    > > and virtual destruction , then you'll get the conclusion
    > > that inheritance from standard containors will be dangerous.


    > With public inheritance maybe, but you can't point a base* to
    > a derived object if derived uses private inheritance.


    You can, and in fact, one frequent use of private inheritance
    involves doing just that. But you need cooperation from the
    derived class to do so: if the derived class doesn't give you
    the Base*, you can't get it otherwise. (The "frequent use" is
    to derive privately from something like "EventHander": for
    normal client code, this is an implementation detail, and they
    can't consider the class to be an EventHander. But the class
    itself may register itself as an EventHander with some
    EventNotifier, who will address the class through an
    EventHander*.)

    > Private inheritance hides the fact that a derived is a base.


    Except in the explicit cases where it wants to behave as a base.

    None of which is really a problem when deriving privately from a
    standard container, since you, the author of the class, have
    total control, and of course, you will not expose the
    derivation.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, May 27, 2008
    #13
    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. =?Utf-8?B?UHJlc3RvbiBQYXJr?=

    Kerberos Delegation Question

    =?Utf-8?B?UHJlc3RvbiBQYXJr?=, Jun 18, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    920
    =?Utf-8?B?UHJlc3RvbiBQYXJr?=
    Jun 18, 2005
  2. russell.lane

    delegation question

    russell.lane, Jan 13, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    363
    Bruce Barker
    Jan 13, 2006
  3. christopher diggins

    delegation class question

    christopher diggins, Apr 26, 2004, in forum: C++
    Replies:
    2
    Views:
    319
    Christopher Diggins
    Apr 29, 2004
  4. JimLad
    Replies:
    4
    Views:
    452
    Ken Cox [Microsoft MVP]
    Nov 2, 2006
  5. Sam Roberts
    Replies:
    4
    Views:
    323
    Sam Roberts
    May 7, 2008
Loading...

Share This Page