Topic: Exposing private/protected members
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/30 Raw View
Francis Glassborow wrote:
> In article <365EC1DE.92F32057@wizard.net>, James Kuyper
> <kuyper@wizard.net> writes
> >I don't see how accidentally typing:
> >
> > using Base::f;
> I can type this because I want to inject an overloaded set of
> identifiers. That is not accidental. What is accidental is that by
> doing so I convert an unnoticed protected member of the base class set
> to a public member of the derived class
> >
> >is any more likely than accidentally typing:
> >
> > void f() { Base::f(); }
> This explicitly forwards to a single specified function.
> What worries me is that you appear to find it difficult to see the
> difference between and explicit forwarding function and injection of all
> uses of an identifier public and protected into a derived public
> interface. They are very different things.
I see the problem now. I wasn't thinking in terms of a set of function
overloads with different access modes.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/27 Raw View
In article <365c4781.58577304@news.motu.com>, David Abrahams
<abrahams@spam.motu.com> writes
>I don't think any new capability was added here, just a more
>convenient syntax. If a subclass has protected access to a base class
>member, it can always give full access to the wide world by declaring
>a public forwarding function (or, if it's a data member, a public
>reference or pointer). This doesn't sound like any new holes were
>opened up. Am I missing something?
I will say it just one more time and then shut up about it here.
The difference is between making a (hopefully) carefully considered
decision to over-rule the base class designer's decision to restrict
access and being able to do so by accident. I think that matters and
many of you obviously think otherwise.
Perhaps one of the tool vendors will provide a tool that will highlight
such dubious coding.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/28 Raw View
In article <365C42CB.41C6@wizard.net>, James Kuyper <kuyper@wizard.net>
writes
>Is the difference between D1 and D2 worth worrying about?
Yes, because D1 requires a conscious decision and D2 does not.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/28 Raw View
Francis Glassborow wrote:
>
> In article <365c4781.58577304@news.motu.com>, David Abrahams
> <abrahams@spam.motu.com> writes
> >I don't think any new capability was added here, just a more
> >convenient syntax. If a subclass has protected access to a base class
> >member, it can always give full access to the wide world by declaring
> >a public forwarding function (or, if it's a data member, a public
> >reference or pointer). This doesn't sound like any new holes were
> >opened up. Am I missing something?
>
> I will say it just one more time and then shut up about it here.
>
> The difference is between making a (hopefully) carefully considered
> decision to over-rule the base class designer's decision to restrict
> access and being able to do so by accident. I think that matters and
> many of you obviously think otherwise.
I don't see how accidentally typing:
using Base::f;
is any more likely than accidentally typing:
void f() { Base::f(); }
Why do you think otherwise?
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/29 Raw View
In article <365EC1DE.92F32057@wizard.net>, James Kuyper
<kuyper@wizard.net> writes
>I don't see how accidentally typing:
>
> using Base::f;
I can type this because I want to inject an overloaded set of
identifiers. That is not accidental. What is accidental is that by
doing so I convert an unnoticed protected member of the base class set
to a public member of the derived class
>
>is any more likely than accidentally typing:
>
> void f() { Base::f(); }
This explicitly forwards to a single specified function.
What worries me is that you appear to find it difficult to see the
difference between and explicit forwarding function and injection of all
uses of an identifier public and protected into a derived public
interface. They are very different things.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/29 Raw View
Francis Glassborow wrote:
> In article <365C42CB.41C6@wizard.net>, James Kuyper <kuyper@wizard.net>
> writes
> >Is the difference between D1 and D2 worth worrying about?
> Yes, because D1 requires a conscious decision and D2 does not.
I just don't see that; they look like equally conscious decisions to me.
I guess we'll just have to agree to disagree.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/25 Raw View
Francis Glassborow wrote:
>
> In article <365B6873.F54C9A9F@wizard.net>, James Kuyper
> <kuyper@wizard.net> writes
> >Whenever you declare something protected, you're placing your trust in
> >the developers who derived from your base class. Trust is always a risk,
> >and should be avoided when the risk becomes unacceptable.
>
> True, but the point of protected access is that not all users of my
> class are equally trustworthy. Using declarations implicitly remove a
> layer of protection.
As has been shown elsewhere, no such layer of protection exists; the
derived class already has full access to the protected members of the
base class, and can expose them publicly without the use of 'using'; the
required syntax is just a little more complicated:
class Base{
protected:
int a;
void f() {};
public:
Base() : a(0) {}
};
class D1 : public Base {
public:
int &a;
void f() { Base::f(); }
D1() : a(Base::a) {}
};
class D2 : public Base {
public:
using Base::a;
using Base::f;
D2() {};
};
Is the difference between D1 and D2 worth worrying about?
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: abrahams@spam.motu.com (David Abrahams)
Date: 1998/11/26 Raw View
On 25 Nov 98 16:17:17 GMT, Francis Glassborow
<francis@robinton.demon.co.uk> wrote:
>In article <365B6873.F54C9A9F@wizard.net>, James Kuyper
><kuyper@wizard.net> writes
>>Whenever you declare something protected, you're placing your trust in
>>the developers who derived from your base class. Trust is always a risk,
>>and should be avoided when the risk becomes unacceptable.
>
>True, but the point of protected access is that not all users of my
>class are equally trustworthy. Using declarations implicitly remove a
>layer of protection.
>
>The result is that if I want to restrict use of an overload set by
>making some of them available only to trustworthy class developers I
>must contort my code by making one of the overload set private (and
>perhaps providing a differently named protected forwarding function)
As far as I know, there has never been a technique in C++ for
restricting access or capability based on the identity of the
programmer attempting access. Are you seriously suggesting that this
is a problem with the language?
>But by adding a private member to the overload set I can really get up
>the noses of those deriving from my class because they have to
>explicitly inject the required functions (use the original, and now
>deprecated mechanism)
>
>IMHO the current specification is a defect which it seems we are now
>stuck with because by the time we get a chance to change it there will
>be reams of code depending on it (and possibly actually broken as a
>result)
>
>I just do not think we gave sufficient consideration to the differences
>between namespaces and classes when we extended using declarations to
>classes.
I don't think any new capability was added here, just a more
convenient syntax. If a subclass has protected access to a base class
member, it can always give full access to the wide world by declaring
a public forwarding function (or, if it's a data member, a public
reference or pointer). This doesn't sound like any new holes were
opened up. Am I missing something?
-Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/25 Raw View
Francis Glassborow wrote:
....
> Yes but you rightly use the language of crime:) I am concerned that
> using declarations can unintentionally inject protected functions (that
> would be trapped by the compiler in the base class) as publicly
If it should be trapped in the base class, it should be declared
private, not protected.
> accessible (and hence not trapped) in a derived class. We have enough
> potential problem with unexpected overload resolutions without adding
> that a using declaration can remove the protection provided by the base
> class author.
>
> Now before writing a using delaration I have to carefully study present
> and future <g> uses of the identifier in the base class.
Whenever you declare something protected, you're placing your trust in
the developers who derived from your base class. Trust is always a risk,
and should be avoided when the risk becomes unacceptable.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/25 Raw View
In article <365B6873.F54C9A9F@wizard.net>, James Kuyper
<kuyper@wizard.net> writes
>Whenever you declare something protected, you're placing your trust in
>the developers who derived from your base class. Trust is always a risk,
>and should be avoided when the risk becomes unacceptable.
True, but the point of protected access is that not all users of my
class are equally trustworthy. Using declarations implicitly remove a
layer of protection.
The result is that if I want to restrict use of an overload set by
making some of them available only to trustworthy class developers I
must contort my code by making one of the overload set private (and
perhaps providing a differently named protected forwarding function)
But by adding a private member to the overload set I can really get up
the noses of those deriving from my class because they have to
explicitly inject the required functions (use the original, and now
deprecated mechanism)
IMHO the current specification is a defect which it seems we are now
stuck with because by the time we get a chance to change it there will
be reams of code depending on it (and possibly actually broken as a
result)
I just do not think we gave sufficient consideration to the differences
between namespaces and classes when we extended using declarations to
classes.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: hsutter@peerdirect.com (Herb Sutter)
Date: 1998/11/24 Raw View
NOTE: I am not encouraging the following as good coding practice.
However, it's worth noting that certain prominent authors do teach
this hack and even advocate its use in restricted cases.
On 18 Nov 98 15:54:46 GMT, jim.hyslop@leitch.com wrote:
>Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
>> Did I miss something (likely) but I did not know that a using
>> declaration could slacken the access constraint of a base class member.
>Oh, God, I hope they can't. If that were the case, all you'd have to do to
>violate encapsulation would be:
Well, you can already write portable code that completely bypasses
access restrictions on any class, as long as it has a member template.
// Innocent header file c.h
//
class C {
// everything is private
template<class T> void f(T);
};
To hijack this, just specialize the template using a class of your own
(locally declared classes, or classes in an unnamed namespace, work
wonderfully and guarantee that you won't violate the ODR). I call this
the "anyone who wants to can be a member" trick.
Here's an example, modulo typos (I didn't run it through a compiler):
// Pernicious and depraved (but portable!) calling code
//
namespace {
struct X { /* whatever information you need to get into a C */ };
template<>
void C::f<X>( X x ) {
// do whatever you like to this C object...
// as a member you have full access here
}
// elsewhere:
C c;
c.f( X(/*...*/) ); // do whatever you like to c
}
This should be portable (whereas the old "redefine a nontemplate
member" trick isn't because it violates the ODR), and you could even
argue that it's justified in cases were C has a demonstrably broken
public interface.
Herb
---
Herb Sutter (mailto:hsutter@peerdirect.com)
PeerDirect Inc. 2695 North Sheridan Way, Suite 150
www.peerdirect.com Mississauga Ontario Canada L5K 2N6
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/24 Raw View
In article <3658bada.5110817@nr1.toronto.istar.net>, Herb Sutter
<hsutter@peerdirect.com> writes
>Well, you can already write portable code that completely bypasses
>access restrictions on any class, as long as it has a member template.
>
> // Innocent header file c.h
> //
> class C {
> // everything is private
> template<class T> void f(T);
> };
>
>To hijack this, just specialize the template using a class of your own
>(locally declared classes, or classes in an unnamed namespace, work
>wonderfully and guarantee that you won't violate the ODR). I call this
>the "anyone who wants to can be a member" trick.
Yes but you rightly use the language of crime:) I am concerned that
using declarations can unintentionally inject protected functions (that
would be trapped by the compiler in the base class) as publicly
accessible (and hence not trapped) in a derived class. We have enough
potential problem with unexpected overload resolutions without adding
that a using declaration can remove the protection provided by the base
class author.
Now before writing a using delaration I have to carefully study present
and future <g> uses of the identifier in the base class.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/20 Raw View
In article <3653B76C.942A75CA@wizard.net>, James Kuyper
<kuyper@wizard.net> writes
>I think the simplest rationale is that it simplifies the code. A derived
>class has access to any protected members of its base class, and can
>create members and functions that publicly expose that member. The
>using-directive simply makes it easier. Consider the following:
But it also makes accidental exposure possible/likely.
I may have an overloaded set of functions with one dangerous case that
has been declared with protected access because those deriving from my
classmay need it but a user should get an access violation.
I think we now need to add a guideline:
Never overload a function with versions that are protected and public
unless at least one is private. We also need static analysis that
detects breaches of this guideline.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hyman Rosen <hymie@prolifics.com>
Date: 1998/11/20 Raw View
Francis Glassborow wrote:
> I'll take your word for it for now but that worries me, when and why did
> we allow this?
After all, why not? You could always do the following:
struct A { protected: int a; };
struct B : A { int &A_a() { return a; } };
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/21 Raw View
In article <3655B29B.6D2C5434@prolifics.com>, Hyman Rosen
<hymie@prolifics.com> writes
>struct A { protected: int a; };
>struct B : A { int &A_a() { return a; } };
Yes, but that relies on an explicit decision, using declarations make
that decision implicitly even when not intended.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/18 Raw View
jim.hyslop@leitch.com wrote:
> In article <UhtAUgBjViU2EwBi@robinton.demon.co.uk>,
> Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
> >
> > In article <3651FA3A.59E2@wizard.net>, James Kuyper <kuyper@wizard.net>
> > writes
> > >The fact that this can be done (assuming I did it right - I'm still
> > >somewhat confused by name look-up and using-declarations) is one of the
> > >reasons why you should be careful about defining any member 'protected'.
> > >You usually want either 'public' or 'private'.
> >
> > Did I miss something (likely) but I did not know that a using
> > declaration could slacken the access constraint of a base class member.
> Oh, God, I hope they can't. If that were the case, all you'd have to do to
> violate encapsulation would be:
> class base
> {
> private:
> int x,y,z;
> };
> class violator: public base
> {
> public:
> using base::x;
> using base::y;
> using base::z;
> };
Not permitted; violator doesn't have access to x,y, or z, because
they're private. However, it would be legal if they were protected,
which corresponds to my example.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/11/19 Raw View
In article <3651F5EA.B176B6E5@acm.org>,
Pete Becker <petebecker@acm.org> wrote:
> AllanW@my-dejanews.com wrote:
> >
> > In article <72qnm6$s9d$1@newsmonger.rutgers.edu>,
> > "Ajay Wanchoo" <wanchoo@caip.rutgers.edu> wrote:
> > > I just want an opinion of the experts on the following situation:
> > >
> > > Should the exposing of private / protected members (as done below by B)
be
> > > trapped by the compilers.
> > >
> > > class A
> > > {
> > > private:
> > > int a,b;
> > > public:
> > > A()
> > > {
> > > a = b = 0;
> > > }
> > > };
> > >
> > > class B
> > > {
> > > public:
> > > int a,b;
> > > public:
> > > A()
> > ^^^ Assume you meant B()
> > > {
> > > a = b = 0;
> > > }
> > > }
> > >
> > > void main()
> > > {
> >
> > Interesting definition of main(), you may have some more writing
> > to do... :^)
> >
> > Anyway, you're mistaken. B does not "expose" any private or
> > protected elements of A. Instead, B objects have an A sub-object
> > (including int a and int b), AND ALSO have their own int a and
> > int b.
>
> Nope, you made the same mistake I did. Look more closely: B is not
> derived from A.
Ooh, you're right.
Obviously the post got truncated. Where was Ajay going with this?
Perhaps construct an A, and then cast it's address to a B-pointer
to access the elements?
Ajay, C++'s design philosophy is to prevent accidents, not fraud.
So you won't be able to access A's private members unless you use
a cast, which is C++'s "pass key". The pass key can be used for
good or for evil; what you seem to have in mind is definately evil.
Avoid it.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/19 Raw View
In article <3652E265.2781@wizard.net>, James Kuyper <kuyper@wizard.net>
writes
>The alias created by the using-declaration has the usual accessibility
>for a member-declaration. [Example:
> class A {
> private:
> void f(char);
> public:
> void f(int);
> protected:
> void g();
> };
>
> class B : public A {
> using A::f; // error: A::f(char) is inaccessible
> public:
> using A::g; // B::g is a public synonym for A::g
> };
Yes I see the example however I think it does not match the text.
I think the 'usual accessibility' was intended to mean that you could
not use a using declaration of a name in a base class if any use of that
name were private (I think that was unnecessarily restrictive) and that
other cases would inherit the access specifier from the base unless the
using declaration was more restrictive. If this was not the intent then
I would like to see a rationale to justify the comment on using A::g;
above.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jim.hyslop@leitch.com
Date: 1998/11/19 Raw View
In article <JgzX0$AafzU2EwSU@robinton.demon.co.uk>,
Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
> In article <3652E265.2781@wizard.net>, James Kuyper <kuyper@wizard.net>
> writes
> >The alias created by the using-declaration has the usual accessibility
> >for a member-declaration. [Example:
> > class A {
> > private:
> > void f(char);
> > public:
> > void f(int);
> > protected:
> > void g();
> > };
> >
> > class B : public A {
> > using A::f; // error: A::f(char) is inaccessible
> > public:
> > using A::g; // B::g is a public synonym for A::g
> > };
> Yes I see the example however I think it does not match the text.
> I think the 'usual accessibility' was intended to mean that you could
> not use a using declaration of a name in a base class if any use of that
> name were private (I think that was unnecessarily restrictive) and that
> other cases would inherit the access specifier from the base unless the
> using declaration was more restrictive. If this was not the intent then
> I would like to see a rationale to justify the comment on using A::g;
> above.
The wording does seem to be rather vague and difficult to interpret (IMO, of
course). But that sentence is not alone in that regards :-)
It seems to me the intent of that clause is to state that a using declaration
can only be applied to members that would normally be accessible to the base
class. Since private members are not accessible to the derived class, you
cannot apply a using declaration to them. Protected members are accessible,
therefore it is legal to apply the using declaration to them (however
questionable the motives).
--
Jim
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/20 Raw View
In article <365306DD.446B@wizard.net>, James Kuyper <kuyper@wizard.net>
writes
>Not permitted; violator doesn't have access to x,y, or z, because
>they're private. However, it would be legal if they were protected,
>which corresponds to my example.
I'll take your word for it for now but that worries me, when and why did
we allow this?
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/11/20 Raw View
In article <72srbu$klk$1@newsmonger.rutgers.edu>,
"Ajay Wanchoo" <wanchoo@caip.rutgers.edu> wrote:
> >Anyway, you're mistaken. B does not "expose" any private or
> >protected elements of A. Instead, B objects have an A sub-object
> >(including int a and int b), AND ALSO have their own int a and
> >int b.
>
> I'm not so sure, I had NOT derived (inherited) B from A class, I had cast,
> A to B (see reposted article).If you check the value that sizeof returns
> for either of the two classes defined you'll see that they are identical.
You're right. With main() incomplete, I didn't know where you were
going, and I didn't look closely enough at the classes.
> >If A had declared a and b private, then B could access them as
> >A::a and A::b. B can also access it's own integers as B::a or
> >simply a, and B::b or simply b.
>
> You used protected variables to demonstrate your point. However
> you mentioned that from B (which you derived from A) one could access
> them (defined private in A) as A::a and A::b, are you sure ?
>
> I could use:
> B &b = dynamic_cast<B&>(a);
> for safe casting (this would not compile, the earlier case would).
> This was suggested by a kind soul in another newsgroup.
This shouldn't compile okay because object a isn't a B object.
However, if both A and B have at least one virtual function then
it SHOULD compile okay -- and throw an exception at runtime for
precisely the same reason.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/20 Raw View
Francis Glassborow wrote:
>
> In article <3652E265.2781@wizard.net>, James Kuyper <kuyper@wizard.net>
> writes
> >The alias created by the using-declaration has the usual accessibility
> >for a member-declaration. [Example:
> > class A {
> > private:
> > void f(char);
> > public:
> > void f(int);
> > protected:
> > void g();
> > };
> >
> > class B : public A {
> > using A::f; // error: A::f(char) is inaccessible
> > public:
> > using A::g; // B::g is a public synonym for A::g
> > };
>
> Yes I see the example however I think it does not match the text.
>
> I think the 'usual accessibility' was intended to mean that you could
> not use a using declaration of a name in a base class if any use of that
> name were private (I think that was unnecessarily restrictive) and that
I agree, and that's consistent with the example.
> other cases would inherit the access specifier from the base unless the
> using declaration was more restrictive. If this was not the intent then
> I would like to see a rationale to justify the comment on using A::g;
> above.
I think the simplest rationale is that it simplifies the code. A derived
class has access to any protected members of its base class, and can
create members and functions that publicly expose that member. The
using-directive simply makes it easier. Consider the following:
class A
{
protected:
int i;
void f();
public:
A(int n=0): i(n) {};
}
class B : public A
{
int &i;
B(int n=0): A(n), i(&A::i) { }
f() { A::f(); }
}
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/11/17 Raw View
In article <72qnm6$s9d$1@newsmonger.rutgers.edu>,
"Ajay Wanchoo" <wanchoo@caip.rutgers.edu> wrote:
> I just want an opinion of the experts on the following situation:
>
> Should the exposing of private / protected members (as done below by B) be
> trapped by the compilers.
>
> class A
> {
> private:
> int a,b;
> public:
> A()
> {
> a = b = 0;
> }
> };
>
> class B
> {
> public:
> int a,b;
> public:
> A()
^^^ Assume you meant B()
> {
> a = b = 0;
> }
> }
>
> void main()
> {
Interesting definition of main(), you may have some more writing
to do... :^)
Anyway, you're mistaken. B does not "expose" any private or
protected elements of A. Instead, B objects have an A sub-object
(including int a and int b), AND ALSO have their own int a and
int b.
A B
+-------+ +----------------+
| int a | | base A : int a |
+-------+ } +-------+
| int b | } : int b |
+-------+ +----------------+
| int a |
+----------------+
| int b |
+----------------+
If A had declared a and b private, then B could access them as
A::a and A::b. B can also access it's own integers as B::a or
simply a, and B::b or simply b.
#include <iostream>
class A {
protected:
int a, b;
public:
A() { a = b = 0; }
~A() { std::cout << "A: a=" << a << ", b=" << b << std::endl; }
};
class B : public A {
protected:
int a, b;
public:
B() { a = b = 0; }
~B() { std::cout << "B: a=" << a << ", b=" << b
<< ", A::a=" << A::a << ", A::b=" << A::b << std::endl; }
void func(int i, int j, int k, int l) {
A::a = i; A::b = j; B::a = k; B::b = l;
}
};
int main() {
B var;
var.func(2, 4, 6, 8);
return 0;
}
The output happens after the return 0, when var is destroyed.
(Remember that after B's destructor executes, A's destructor
also executes.) The output is:
B: a=6, b=8, A::a=2, A::b=4
A: a=2, b=4
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/17 Raw View
Ajay Wanchoo wrote:
>
> I just want an opinion of the experts on the following situation:
>
> Should the exposing of private / protected members (as done below by B) be
> trapped by the compilers.
>
> class A
> {
> private:
> int a,b;
> public:
> A()
> {
> a = b = 0;
> }
> };
>
> class B
Did you leave out a ": public A" here? Your example has no protected
members of A. Even if B were derived from A, it would have no access to
the private members of A, so it couldn't expose them.
> {
> public:
> int a,b;
Even if B were derived from A, B::a would be a completely different
object than A::a.
> public:
> A()
I hope you didn't intend this to be a constructor. It isn't, because the
syntax is wrong. You can't define a constructor for A in B, and a
constructor for B must is identified using B().
> {
> a = b = 0;
> }
> }
Is this what you're trying to do?
class A {
protected:
int a;
// other members.
};
class B : public A {
public:
using A:a;
// other members.
};
The fact that this can be done (assuming I did it right - I'm still
somewhat confused by name look-up and using-declarations) is one of the
reasons why you should be careful about defining any member 'protected'.
You usually want either 'public' or 'private'.
I think this is a perfectly legitimate technique, if used carefully. Of
course, it will be misused.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/11/18 Raw View
AllanW@my-dejanews.com writes:
>In article <72qnm6$s9d$1@newsmonger.rutgers.edu>,
> "Ajay Wanchoo" <wanchoo@caip.rutgers.edu> wrote:
>> Should the exposing of private / protected members (as done below by B) be
>> trapped by the compilers.
>>
>> class A
>> {
>> private:
>> int a,b;
>> public:
>> A()
>> {
>> a = b = 0;
>> }
>> };
>>
>> class B
>> {
>> public:
>> int a,b;
>> public:
>> A()
> ^^^ Assume you meant B()
>> {
>> a = b = 0;
>> }
>> }
>Anyway, you're mistaken. B does not "expose" any private or
>protected elements of A. Instead, B objects have an A sub-object
>(including int a and int b), AND ALSO have their own int a and
>int b.
But B is not derived from A and does not contain an A.
I think the point was to define a parallel class B in which
the members were not private, then use type punning to get at
the private members.
The original post was missing the definition of main that did just
that. A follow-up post was more complete.
I discussed these issues in a reply to the second article.
--
Steve Clamage, stephen.clamage@sun.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/18 Raw View
In article <3651FA3A.59E2@wizard.net>, James Kuyper <kuyper@wizard.net>
writes
>The fact that this can be done (assuming I did it right - I'm still
>somewhat confused by name look-up and using-declarations) is one of the
>reasons why you should be careful about defining any member 'protected'.
>You usually want either 'public' or 'private'.
Did I miss something (likely) but I did not know that a using
declaration could slacken the access constraint of a base class member.
>
>I think this is a perfectly legitimate technique, if used carefully. Of
>course, it will be misused.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Chris Ahlstrom <ahlstroc@bellsouth.net>
Date: 1998/11/18 Raw View
This topic sounds like something the President might want to think about.
Seriously, this sounds like a lint thing, not a compiler thing.
If you make the compiler legislate every permutation of code,
I think you drive the programmer crazy, and add a lot of
#pragmas to give the programmer more wiggle room.
If the programmer is too tired or lazy to detect things like that,
why would he/she want to add a bunch of #pragmas???
Most programmers I know let warning messages proliferate anyway.
Let them eat lint.
Chris
Ajay Wanchoo wrote:
> I just want an opinion of the experts on the following situation:
>
> Should the exposing of private / protected members (as done below by B) be
> trapped by the compilers.
>
> class A
> {
> private:
> int a,b;
> public:
> A()
> {
> a = b = 0;
> }
> };
>
> class B
> {
> public:
> int a,b;
> public:
> A()
> {
> a = b = 0;
> }
> }
>
> void main()
> {
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting with ]
> [ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. --- ]
> [ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
--
Chris Ahlstrom
major league software, llc
1259 Center Lake Dr.
Mt. Pleasant, SC 29464-7419
(843)849-0985
a h l s t r o c @bellsouth.net
They don't let Bill Gates code anymore.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: William Roeder <roeder@dba-sys.com>
Date: 1998/11/18 Raw View
Ajay Wanchoo wrote:
>
> I just want an opinion of the experts on the following situation:
>
> Should the exposing of private / protected members (as done below by B) be
> trapped by the compilers.
>
> class A
> {
> private:
> int a,b;
> public:
> A()
this ^ is the constructor for A
> {
> a = b = 0;
> }
> };
>
> class B
> {
> public:
> int a,b;
> public:
> A()
this ^ is a function call of B that modifies B's public data. It has
nothing to do with class A.
> {
> a = b = 0;
> }
> }
So what do you mean by "exposing of private / protected members"
--
Bill Roeder
My opinions are my own and do not reflect those of my employer.
Why do people put the above line in their signature?
If they reflected my employer then he would have sent the message!
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Ajay Wanchoo" <wanchoo@caip.rutgers.edu>
Date: 1998/11/18 Raw View
>> A()
> ^^^ Assume you meant B()
I stand corrected.
>Interesting definition of main(), you may have some more writing
>to do... :^)
Actually it got truncated see the *reposted* article.
>Anyway, you're mistaken. B does not "expose" any private or
>protected elements of A. Instead, B objects have an A sub-object
>(including int a and int b), AND ALSO have their own int a and
>int b.
I'm not so sure, I had NOT derived (inherited) B from A class, I had cast,
A to B (see reposted article).If you check the value that sizeof returns
for either of the two classes defined you'll see that they are identical.
>If A had declared a and b private, then B could access them as
>A::a and A::b. B can also access it's own integers as B::a or
>simply a, and B::b or simply b.
You used protected variables to demonstrate your point. However
you mentioned that from B (which you derived from A) one could access
them (defined private in A) as A::a and A::b, are you sure ?
I could use:
B &b = dynamic_cast<B&>(a);
for safe casting (this would not compile, the earlier case would).
This was suggested by a kind soul in another newsgroup.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1998/11/18 Raw View
AllanW@my-dejanews.com wrote:
>
> In article <72qnm6$s9d$1@newsmonger.rutgers.edu>,
> "Ajay Wanchoo" <wanchoo@caip.rutgers.edu> wrote:
> > I just want an opinion of the experts on the following situation:
> >
> > Should the exposing of private / protected members (as done below by B) be
> > trapped by the compilers.
> >
> > class A
> > {
> > private:
> > int a,b;
> > public:
> > A()
> > {
> > a = b = 0;
> > }
> > };
> >
> > class B
> > {
> > public:
> > int a,b;
> > public:
> > A()
> ^^^ Assume you meant B()
> > {
> > a = b = 0;
> > }
> > }
> >
> > void main()
> > {
>
> Interesting definition of main(), you may have some more writing
> to do... :^)
>
> Anyway, you're mistaken. B does not "expose" any private or
> protected elements of A. Instead, B objects have an A sub-object
> (including int a and int b), AND ALSO have their own int a and
> int b.
Nope, you made the same mistake I did. Look more closely: B is not
derived from A.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/18 Raw View
In article <72qnm6$s9d$1@newsmonger.rutgers.edu>, Ajay Wanchoo
<wanchoo@caip.rutgers.edu> writes
>I just want an opinion of the experts on the following situation:
>
>Should the exposing of private / protected members (as done below by B) be
>trapped by the compilers.
why should they? The code is perfectly legal and there are even coding
styles where it might be acceptable.
>
>class A
>{
> private:
> int a,b;
> public:
> A()
> {
> a = b = 0;
> }
>};
>
>class B
>{
> public:
> int a,b;
> public:
> A()
> {
> a = b = 0;
> }
>}
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jim.hyslop@leitch.com
Date: 1998/11/18 Raw View
In article <UhtAUgBjViU2EwBi@robinton.demon.co.uk>,
Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
>
> In article <3651FA3A.59E2@wizard.net>, James Kuyper <kuyper@wizard.net>
> writes
> >The fact that this can be done (assuming I did it right - I'm still
> >somewhat confused by name look-up and using-declarations) is one of the
> >reasons why you should be careful about defining any member 'protected'.
> >You usually want either 'public' or 'private'.
>
> Did I miss something (likely) but I did not know that a using
> declaration could slacken the access constraint of a base class member.
Oh, God, I hope they can't. If that were the case, all you'd have to do to
violate encapsulation would be:
class base
{
private:
int x,y,z;
};
class violator: public base
{
public:
using base::x;
using base::y;
using base::z;
};
Footnote 99 in [class.access.base - 11.2] is, I believe, relevant here: "As
specified previously in clause 11, private members of a base class remain
inaccessible even to derived classes unless friend declarations within the
base class declarations are used to grant access explicitly."
This implies - but I could not find explictly stated anywhere - that the using
directive can only operate on members that are accessible by the class. Which
makes sense, as I said above.
--
Jim
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/18 Raw View
Francis Glassborow wrote:
>
> In article <3651FA3A.59E2@wizard.net>, James Kuyper <kuyper@wizard.net>
> writes
> >The fact that this can be done (assuming I did it right - I'm still
> >somewhat confused by name look-up and using-declarations) is one of the
> >reasons why you should be careful about defining any member 'protected'.
> >You usually want either 'public' or 'private'.
>
> Did I miss something (likely) but I did not know that a using
> declaration could slacken the access constraint of a base class member.
Section 7.3.3, p15:
The alias created by the using-declaration has the usual accessibility
for a member-declaration. [Example:
class A {
private:
void f(char);
public:
void f(int);
protected:
void g();
};
class B : public A {
using A::f; // error: A::f(char) is inaccessible
public:
using A::g; // B::g is a public synonym for A::g
};
--end example]
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Ajay Wanchoo" <wanchoo@caip.rutgers.edu>
Date: 1998/11/18 Raw View
Sorry there was a typo out there which most noticed and assumed the
correct thing, i.e.
the following A() is actually B() // (constructor of class B)
>> A()
>this ^ is a function call of B that modifies B's public data. It has
>nothing to do with class A.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Ajay Wanchoo" <wanchoo@caip.rutgers.edu>
Date: 1998/11/17 Raw View
I just want an opinion of the experts on the following situation:
Should the exposing of private / protected members (as done below by B) be
trapped by the compilers.
class A
{
private:
int a,b;
public:
A()
{
a = b = 0;
}
};
class B
{
public:
int a,b;
public:
A()
{
a = b = 0;
}
}
void main()
{
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]