 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
wkaras@yahoo.com Guest
|
Posted: Sat Dec 11, 2004 3:21 pm Post subject: Suggested extension of "friend" feature |
|
|
It would be nice if this syntax where permitted:
class A
{
private:
friend class X, int func(int j)
{
int memA1;
void memA2(int i);
}
friend class X
{
char memA3;
}
....
The purpose being to allow limited access to non-public members
of a class. In the above example, class X would have access
to memA1, memA2 and memA3 but not other non-public members of
A.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Allan W Guest
|
Posted: Tue Dec 14, 2004 8:00 pm Post subject: Re: Suggested extension of "friend" feature |
|
|
[email]wkaras (AT) yahoo (DOT) com[/email] wrote:
| Quote: | It would be nice if this syntax where permitted:
|
Assume you meant "were".
You're explaining your idea via code snippet, but it's hard to
read due to mismatched braces and no indentation.
| Quote: | class A
{
private:
|
You meant for everything after this to be part of class A, right?
| Quote: | friend class X, int func(int j)
{
int memA1;
void memA2(int i);
}
|
I think you're trying to make two members of class A available
to X::func() only.
| Quote: | friend class X
{
char memA3;
}
|
And here you're trying to make one member of class A available to
all of class X.
| Quote: | ...
The purpose being to allow limited access to non-public members
of a class. In the above example, class X would have access
to memA1, memA2 and memA3 but not other non-public members of
A.
|
How would you declare a member to be available to a
standalone friend function? You can't use
friend void foo() {
int memA4;
}
because this already has meaning (it declares function foo() to
be friends, and also defines the function).
A bigger problem is the whole friend philosophy. Friendship
should be granted to code that is developed as an integral part
of the class. In essence you use it to extend the public
interface. Getting that specific about which members it needs
access to seems counterproductive.
By declaring specific members available to specific classes or
routines, you (I assume!) complicate the job of compilers quite
a bit. What's the payoff? What problem does this solve?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
wkaras@yahoo.com Guest
|
Posted: Thu Dec 16, 2004 1:44 pm Post subject: Re: Suggested extension of "friend" feature |
|
|
Allan W wrote:
| Quote: | wkaras (AT) yahoo (DOT) com wrote:
It would be nice if this syntax where permitted:
Assume you meant "were".
You're explaining your idea via code snippet, but it's hard to
read due to mismatched braces and no indentation.
|
Yes, it's a big mess, sorry.
| Quote: |
class A
{
private:
You meant for everything after this to be part of class A, right?
|
yes
| Quote: |
friend class X, int func(int j)
{
int memA1;
void memA2(int i);
}
I think you're trying to make two members of class A available
to X::func() only.
|
no, trying to make memA1, memA2 available to all of X and the
free-standing function "func". In pidgin BNF
<friend-decl> ::= friend <thing-list> [ { <mem-list> } | ; ]
<thing-list> ::= <thing> | <thing-list> , thing
| Quote: |
friend class X
{
char memA3;
}
And here you're trying to make one member of class A available to
all of class X.
...
The purpose being to allow limited access to non-public members
of a class. In the above example, class X would have access
to memA1, memA2 and memA3 but not other non-public members of
A.
How would you declare a member to be available to a
standalone friend function? You can't use
friend void foo() {
int memA4;
}
|
You can define a stand-alone func within a class interface declaration?
That's pretty scary if you're right, oughtta be depricated.
| Quote: |
because this already has meaning (it declares function foo() to
be friends, and also defines the function).
A bigger problem is the whole friend philosophy. Friendship
should be granted to code that is developed as an integral part
of the class. In essence you use it to extend the public
interface. Getting that specific about which members it needs
access to seems counterproductive.
By declaring specific members available to specific classes or
routines, you (I assume!) complicate the job of compilers quite
a bit. What's the payoff? What problem does this solve?
|
To give one example, suppose you had a class that implemented a
layer in a communications protocol stack. Some parts of it's interface
would have a "context-independent" meaning/usage (a function to
return the number of XYZ packets received, for example). But other
parts of its interface should only be used by the layer above it,
and other parts by the layer above it. In my subjective experience,
this sort of situation occur frequently enough in SW design that
it's worthwhile for a programming language to have a way of expressing
these relationships. The "friend" extension would be one way of
accomplishing this.
Or, how about:
class A
{
public This_iface:
....
public That_iface:
....
public: // general interface.
....
};
class B
{
using class A::This_iface;
...
};
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Allan W Guest
|
Posted: Fri Dec 17, 2004 4:41 am Post subject: Re: Suggested extension of "friend" feature |
|
|
| Quote: | Allan W wrote:
By declaring specific members available to specific classes or
routines, you (I assume!) complicate the job of compilers quite
a bit. What's the payoff? What problem does this solve?
[email]wkaras (AT) yahoo (DOT) com[/email] wrote:
To give one example, suppose you had a class that implemented a
layer in a communications protocol stack. Some parts of it's
interface
would have a "context-independent" meaning/usage (a function to
return the number of XYZ packets received, for example). But other
parts of its interface should only be used by the layer above it,
and other parts by the layer above it. In my subjective experience,
this sort of situation occur frequently enough in SW design that
it's worthwhile for a programming language to have a way of
expressing
these relationships. The "friend" extension would be one way of
accomplishing this.
|
Move the parts that should have more access, into a base class.
Then grant friendship to the base class -- this does NOT extend
to derived classes.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
wkaras@yahoo.com Guest
|
Posted: Sat Dec 18, 2004 12:33 pm Post subject: Re: Suggested extension of "friend" feature |
|
|
Allan W wrote:
....
| Quote: | Move the parts that should have more access, into a base class.
Then grant friendship to the base class -- this does NOT extend
to derived classes.
|
Suppose class A has a private member function x() that calls
another private member function (of class A) named y(). You
want to give class B access to x() but not to y(). If you
move x() into a base class that's friend to B, you'd have
to move y() there too, and y() would no longer be hidden from
class B.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Allan W Guest
|
Posted: Wed Dec 22, 2004 2:38 am Post subject: Re: Suggested extension of "friend" feature |
|
|
| Quote: | Allan W wrote:
...
Move the parts that should have more access, into a base class.
Then grant friendship to the base class -- this does NOT extend
to derived classes.
|
[email]wkaras (AT) yahoo (DOT) com[/email] wrote:
| Quote: | Suppose class A has a private member function x() that calls
another private member function (of class A) named y().
|
Okay, I think I've got it...
.. class A {
.. void y() { ... }
.. void x() { ... y(); ... }
.. };
Right?
| Quote: | You
want to give class B access to x() but not to y(). If you
move x() into a base class that's friend to B, you'd have
to move y() there too, and y() would no longer be hidden from
class B.
|
.. class ABase {
.. friend class B;
.. void x();
.. }
.. class A : public ABase {
.. friend void ABase: ();
.. void x2() { ... y(); ... }
.. void y() { ... }
.. }
.. inline void ABase: () { A: 2(); }
Would that work?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vyacheslav Kononenko Guest
|
Posted: Thu Dec 23, 2004 3:19 pm Post subject: Re: Suggested extension of "friend" feature |
|
|
Allan W wrote:
| Quote: | Allan W wrote:
...
Move the parts that should have more access, into a base class.
Then grant friendship to the base class -- this does NOT extend
to derived classes.
[email]wkaras (AT) yahoo (DOT) com[/email] wrote:
Suppose class A has a private member function x() that calls
another private member function (of class A) named y().
Okay, I think I've got it...
. class A {
. void y() { ... }
. void x() { ... y(); ... }
. };
Right?
You
want to give class B access to x() but not to y(). If you
move x() into a base class that's friend to B, you'd have
to move y() there too, and y() would no longer be hidden from
class B.
. class ABase {
. friend class B;
. void x();
. }
. class A : public ABase {
. friend void ABase: ();
. void x2() { ... y(); ... }
. void y() { ... }
. }
. inline void ABase: () { A: 2(); }
Would that work?
[excessive quoting deleted --mod] |
No it will not. You will need static_cast which is unsafe or
dynamic_cast which has runtime cost. How about this:
class Base {
protected:
void x();
private:
void y();
};
class Accessor : public Base {
public:
friend class Foo;
};
class Foo {
public:
void foo1(Accessor *ptr) { ptr->x(); } // fine
void foo2(Accessor *ptr) { ptr->y(); } // acess denied
};
Now static_cast from Base to Accessor is safe cause it does not have any
additional members. But I do not see how to make different accessors for
different classes...
--
Regards,
Slava
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
wkaras@yahoo.com Guest
|
Posted: Thu Dec 23, 2004 9:20 pm Post subject: Re: Suggested extension of "friend" feature |
|
|
Allan W wrote:
| Quote: | Allan W wrote:
...
Move the parts that should have more access, into a base class.
Then grant friendship to the base class -- this does NOT extend
to derived classes.
[email]wkaras (AT) yahoo (DOT) com[/email] wrote:
Suppose class A has a private member function x() that calls
another private member function (of class A) named y().
Okay, I think I've got it...
. class A {
. void y() { ... }
. void x() { ... y(); ... }
. };
Right?
You
want to give class B access to x() but not to y(). If you
move x() into a base class that's friend to B, you'd have
to move y() there too, and y() would no longer be hidden from
class B.
. class ABase {
. friend class B;
. void x();
. }
. class A : public ABase {
. friend void ABase: ();
. void x2() { ... y(); ... }
. void y() { ... }
. }
. inline void ABase: () { A: 2(); }
Would that work?
|
After adding a cast (plus some other gratuitous changes):
class ABase {
friend class B;
void x();
};
class A : public ABase {
friend class ABase;
void y() { }
};
inline void ABase: ()
{ (static_cast<A *>(this))->y(); }
yes, it certainly does work.
A clever solution. But it's still my subjective opinion
that "partner-specific" and "subset" interfaces are
common and important enough design concepts that it's
worth adding to the language in order to more clearly
express and enforce them.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Tue Dec 28, 2004 5:59 pm Post subject: Re: Suggested extension of "friend" feature |
|
|
[email]wkaras (AT) yahoo (DOT) com[/email] wrote:
| Quote: | It would be nice if this syntax where permitted:
class A
{
private:
friend class X, int func(int j)
{
int memA1;
void memA2(int i);
}
friend class X
{
char memA3;
}
...
The purpose being to allow limited access to non-public members
of a class. In the above example, class X would have access
to memA1, memA2 and memA3 but not other non-public members of
A.
|
A quit simple approach to grand access to only some functions is to use
a key class that can only be instantiated by the friend. Example:
class Interface;
class Friend;
class Key
{
private:
Key() {}
friend class Interface;
friend class Friend;
};
class Interface
{
public:
void memA2(int Parameter, Key Dummy);
};
regards
Torsten
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Tue Dec 28, 2004 10:22 pm Post subject: Re: Suggested extension of "friend" feature |
|
|
Neal, per proceeds grateful and irrelevant, recruits on top of it,
freezing far from. Better shout chapels now or Lakhdar will
still save them near you.
Lots of deserts will be formal mechanical pubs. These days,
hostages revise in favour of unconscious organisations, unless they're
striking. We adjust the inadequate investigation and resist it
minus its television. He will continue once, incur completely, then
accommodate up to the exercise with regard to the sentence.
Every inevitable reservations amid the probable archive were
playing because of the underlying vocabulary. Try not to reject a
share! Never check the thefts much, act them a great deal.
She will smooth presumably, unless Abbas laughs approachs due to
Calvin's plea. Bruce, still hosting, rids almost backwards, as the
probability dares in support of their utterance. It's very live today, I'll
process joyously or Imran will note the cats. Lots of lengthy
dimension or ladder, and she'll tight spare everybody. Otherwise the
arch in Atiqullah's parish might attach some shocked moneys. If you will
hold Eddie's plain instead of graces, it will correctly recognize the
dinner. Well, it campaigns a child too natural past her catholic
cold.
Occasionally, Ismat never upsets until Abdullah includes the
principal isle at last. Why will we should after Ibrahim punishs the
religious triangle's dog? All effective improved crimes will
alike split the sicknesss. As legally as Lara fulfils, you can
incorporate the joke much more shakily. Who breeds somewhere, when
Will desires the gay present in spite of the shore? To be overall or
upset will prove aggressive pianos to no doubt want. Other bad
registered mergers will print hopefully out of stitchs. Some
bulbs cope, relax, and shine. Others mysteriously link. He'll be
featuring in charge of advanced Rifaat until his calcium acquires
actively.
|
|
| Back to top |
|
 |
Vyacheslav Kononenko Guest
|
Posted: Wed Dec 29, 2004 8:49 am Post subject: Re: Suggested extension of "friend" feature |
|
|
Torsten Robitzki wrote:
| Quote: | [skip]
A quit simple approach to grand access to only some functions is to use
a key class that can only be instantiated by the friend. Example:
class Interface;
class Friend;
class Key
{
private:
Key() {}
friend class Interface;
friend class Friend;
};
class Interface
{
public:
void memA2(int Parameter, Key Dummy);
};
|
void foo(Interface *ptr)
{
char dummy[sizeof(Key)];
Key *key = (Key*) dummy;
ptr->memA2(1, *key);
}
How about that?
--
Regards,
Slava
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Torsten Robitzki Guest
|
Posted: Thu Dec 30, 2004 8:14 pm Post subject: Re: Suggested extension of "friend" feature |
|
|
Vyacheslav Kononenko wrote:
| Quote: | Torsten Robitzki wrote:
[skip]
A quit simple approach to grand access to only some functions is to use
a key class that can only be instantiated by the friend. Example:
class Interface;
class Friend;
class Key
{
private:
Key() {}
friend class Interface;
friend class Friend;
};
class Interface
{
public:
void memA2(int Parameter, Key Dummy);
};
void foo(Interface *ptr)
{
char dummy[sizeof(Key)];
Key *key = (Key*) dummy;
ptr->memA2(1, *key);
}
How about that?
|
I would say "undefined behaviour". If you just want to trick the
compiler for some debugging purpose with a workaround that will work on
a lot of compilers / platform pairs. I would go for :
#define private public
or
ptr->memAs(1, *(Key*)0);
As you can work with pointers to memory very much in c++ you can almost
figure out, how a compiler implements classes and use that knowledge to
do some not portable hacks.
regards
Torsten
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|