Partial accessibility to a class's interface

Discussion in 'C++' started by Andy Venikov, May 24, 2004.

  1. Andy Venikov

    Andy Venikov Guest

    Hi all,

    is there a way to make certain functions of a
    class be accessible only by specific class?
    Like "friend class whatever", but only for a few
    functions?

    This could be usefull in a following relationship:

    Client
    / \
    / \
    use/ \use
    / \
    Managed Object<---->Object Manager


    Lets say I have a class Widget.
    I also have a manager for that class, called
    WidgetManager. Widget is accessed by both a client and
    a widget manager. Client shouldn't be able to access functions
    used only by a WidgetManager. But I don't want to make
    WidgetManager a friend of Widget because I want to hide
    implementation details of the Widget from WidgetManager.

    Is there a trick to do that?

    Thanks,
    Andy.
     
    Andy Venikov, May 24, 2004
    #1
    1. Advertising

  2. Andy Venikov wrote:
    > is there a way to make certain functions of a
    > class be accessible only by specific class?


    Extract those functions in a separate class, derive from it,
    and let the "specific class" be a friend of the base class.

    > Like "friend class whatever", but only for a few
    > functions?
    >
    > This could be usefull in a following relationship:
    >
    > Client
    > / \
    > / \
    > use/ \use
    > / \
    > Managed Object<---->Object Manager
    >
    >
    > Lets say I have a class Widget.
    > I also have a manager for that class, called
    > WidgetManager. Widget is accessed by both a client and
    > a widget manager. Client shouldn't be able to access functions
    > used only by a WidgetManager. But I don't want to make
    > WidgetManager a friend of Widget because I want to hide
    > implementation details of the Widget from WidgetManager.
    >
    > Is there a trick to do that?


    Using the proposed scheme, you should get

    class ManagedWidget {
    friend class WidgetManager;
    void do_manage(); // whatever that means...
    };

    class MyWidget : public ManagedWidget {
    void do_some_other_stuff(); // hidden implementation details
    public:
    void do_client_stuff();
    };

    class WidgetManager {
    ...
    void manage_a_widget(ManagedWidget &mw) {
    mw.do_manage();
    }
    };

    Victor
     
    Victor Bazarov, May 24, 2004
    #2
    1. Advertising

  3. Andy Venikov

    Andy Venikov Guest

    <snip>
    > Extract those functions in a separate class, derive from it,
    > and let the "specific class" be a friend of the base class.


    <snip>
    > class ManagedWidget {
    > friend class WidgetManager;
    > void do_manage(); // whatever that means...
    > };
    >
    > class MyWidget : public ManagedWidget {
    > void do_some_other_stuff(); // hidden implementation details
    > public:
    > void do_client_stuff();
    > };
    >
    > class WidgetManager {
    > ...
    > void manage_a_widget(ManagedWidget &mw) {
    > mw.do_manage();
    > }
    > };
    >
    > Victor


    I see. Thanks.

    But there's a problem with this solution. ManagedWidget exposes
    everything to the WidgetManager
    and if do_manage wants to operate with some private data (which would
    always be the case) then that
    private data would be accessible by WidgetManager as well.
    Unless, unless we made do_manage() a virtual function and defined all
    private data in MyWidget.
    But that forces us to do a virtual call where it wasn't necessary
    before.
    Plus, what if I want to restrict client's interface only to a client?
    Client part of the Widget's interface
    may make sense only to clients, not to managers.

    I guess in that case we could use "my firend's friend is not my
    friend" thing and have a common base
    structure with everything a widget needs to know.
    Like this:

    struct WidgetBase
    {
    private:
    //define all widget's gadgets

    friend class ManagedWidget;
    friend class MyWidget;
    friend class AccessedWidget
    };

    class ManagedWidget : virtual WidgetBase
    {
    friend class WidgetManager

    //Specify interface for WidgetManager
    void do_manage()
    {
    //Now we can access all gadgets, which are private in this context
    }
    };

    class AccessedWidget : virtual WidgetBase
    {
    friend class Client;

    //Specify client's interface
    void do_client_stuff()
    {
    //we still can access all the gadgets from here, because we're
    friends with WidgetBase
    }
    };

    class MyWidget : ManagedWidget, AccessedWidget
    {
    public:
    void do_something_visible_to_everyone()
    {
    //we still can access all the gadgets from here, because we're
    friends with WidgetBase
    }
    };


    That seems to work, or am I missing something?

    Thanks,
    Andy.
     
    Andy Venikov, May 26, 2004
    #3
  4. Andy Venikov wrote:
    >
    >
    > I see. Thanks.
    >
    > But there's a problem with this solution. ManagedWidget exposes
    > everything to the WidgetManager
    > and if do_manage wants to operate with some private data (which would
    > always be the case) then that
    > private data would be accessible by WidgetManager as well.
    > Unless, unless we made do_manage() a virtual function and defined all
    > private data in MyWidget.
    > But that forces us to do a virtual call where it wasn't necessary
    > before.


    That's the price you have to pay.
    On the other hand the class names suggest that you are dealing
    with some GUI elements. Does it really matter that much to spend
    0.0000001 seconds in a virtual function call, when the user will
    never notice this delay?

    [snip code which has a lot of friend definitions]

    I wouldn't do it that way.
    That's too much trouble in the long run just to eliminate
    a virtual function call.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, May 26, 2004
    #4
  5. Andy Venikov

    Jerry Coffin Guest

    (Andy Venikov) wrote in message news:<>...
    > Hi all,
    >
    > is there a way to make certain functions of a
    > class be accessible only by specific class?
    > Like "friend class whatever", but only for a few
    > functions?


    No. To me, the fact that you want to indicates that the class in
    question probably isn't very well designed -- specifically it sounds
    like it has a number of basically unrelated responsibilities.

    [ ... ]

    > Lets say I have a class Widget.
    > I also have a manager for that class, called
    > WidgetManager. Widget is accessed by both a client and
    > a widget manager. Client shouldn't be able to access functions
    > used only by a WidgetManager. But I don't want to make
    > WidgetManager a friend of Widget because I want to hide
    > implementation details of the Widget from WidgetManager.


    One possibility would be to use multiple inheritance:

    class UI_object {
    };

    class managed_object {
    };

    class widget : public managed_object, public UI_object {
    // actual implementation of a manageable widget.
    };

    With this scheme, the manager works with managed objects, and the
    client works with UI objects. A widget is both, but code that works
    with one of the base classes only sees the part that it needs to.

    With this scheme, it's fairly common (though not necessary) for the
    base classes to be composed primarily (or exclusively) of pure virtual
    function declarations -- I.e. defining only an interface, not any
    implementation.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, May 27, 2004
    #5
    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. Billy
    Replies:
    2
    Views:
    512
    Billy
    Feb 1, 2006
  2. cyberco
    Replies:
    8
    Views:
    493
    cyberco
    Feb 25, 2006
  3. Thomas Heller
    Replies:
    13
    Views:
    864
    Michele Simionato
    Feb 8, 2007
  4. J. Clifford Dyer

    Re: Partial 1.0 - Partial classes for Python

    J. Clifford Dyer, Feb 8, 2007, in forum: Python
    Replies:
    0
    Views:
    525
    J. Clifford Dyer
    Feb 8, 2007
  5. MurdockSE
    Replies:
    0
    Views:
    887
    MurdockSE
    Sep 13, 2006
Loading...

Share This Page