Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Partial accessibility to a class's interface

Reply
Thread Tools

Partial accessibility to a class's interface

 
 
Andy Venikov
Guest
Posts: n/a
 
      05-24-2004
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.
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      05-24-2004
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
 
Reply With Quote
 
 
 
 
Andy Venikov
Guest
Posts: n/a
 
      05-26-2004
<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.
 
Reply With Quote
 
Karl Heinz Buchegger
Guest
Posts: n/a
 
      05-26-2004
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
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Jerry Coffin
Guest
Posts: n/a
 
      05-27-2004
(E-Mail Removed) (Andy Venikov) wrote in message news:<(E-Mail Removed). com>...
> 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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Partial 1.0 - Partial classes for Python Thomas Heller Python 13 02-08-2007 08:12 PM
Re: Partial 1.0 - Partial classes for Python J. Clifford Dyer Python 0 02-08-2007 05:29 PM
Why? Partial Class within a Partial class Billy ASP .Net 2 02-01-2006 09:10 AM
accessibility of two workgroup =?Utf-8?B?a2luZw==?= Wireless Networking 1 10-19-2005 03:27 PM
asp.net and Web Accessibility Standards Paul G ASP .Net 1 02-26-2004 10:26 PM



Advertisments