Topic: Encapsulation of variables
Author: philparsonage@hotmail.com
Date: Tue, 18 Apr 2006 11:57:05 CST Raw View
I' migrating some code to gcc 4, and I've had to put in rather a lot
of "using" statements into classes that derive from a base class. This
is a pain in the butt, for as far as I can tell no advantage, but what
has scared me more is that I seem to be able to make my private
variables public using this mechanism. That is:
class A {
private: int _fred; /// no-one can see fred directly
};
class B : public A {
public : using A::_fred; /// but this magically turns A::_fred to be
public!
}
int main(int argc, char** argv)
{
B b;
b._fred = 10; // you can do this
return 0;
}
Is this really part of the standard? From reading it, I think it is,
but I can't quite believe what I'm reading! This seems insane!
(You might be able to tell from my madness that we've had a minor
nightmare migrating to gcc 4, and even now it compiles, it's producing
much slower code. I'm not a happy bunny even though it's easter, but I
guess that's not relevant here.)
---
[ 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://www.comeaucomputing.com/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 18 Apr 2006 18:34:39 GMT Raw View
philparsonage@hotmail.com wrote:
> Is this really part of the standard?
No. Perhaps you could post the code that made
you think this was necessary?
(I'm thinking that two-phase template name lookup
is going to be involved, but let's wait and see.)
---
[ 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://www.comeaucomputing.com/csc/faq.html ]
Author: Alberto Ganesh Barbati <AlbertoBarbati@libero.it>
Date: 18 Apr 2006 23:50:02 GMT Raw View
philparsonage@hotmail.com ha scritto:
>
> Is this really part of the standard? From reading it, I think it is,
> but I can't quite believe what I'm reading! This seems insane!
>
No, it isn't part of the standard and my copy of gcc 4.0.2 get it right,
by producing the error message "error: int A::_fred is private". If
the code you posted compiles as-is (something I really doubt) there's
something very wrong with your configuration. Could you double-check,
please?
Ganesh
---
[ 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://www.comeaucomputing.com/csc/faq.html ]
Author: johnchx2@yahoo.com
Date: Tue, 18 Apr 2006 22:56:16 CST Raw View
philparsonage@hotmail.com wrote:
> class A {
> private: int _fred; /// no-one can see fred directly
> };
>
> class B : public A {
> public : using A::_fred; /// but this magically turns A::_fred to be
> public!
> }
>
> int main(int argc, char** argv)
> {
> B b;
> b._fred = 10; // you can do this
> return 0;
> }
>
> Is this really part of the standard?
No, the using declaration in B should not compile, since B has no
access to private members of A. It would be legal if _fred were
protected rather than private, of course.
---
[ 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://www.comeaucomputing.com/csc/faq.html ]
Author: philparsonage@hotmail.com
Date: Wed, 19 Apr 2006 11:19:20 CST Raw View
OK, so maybe my example wasn't the best, I typed a private instead of a
protected. The actual code (which compiles using 4.0.2, or 3.3.6) is:
#include <stdlib.h>
class A {
protected: int _fred;
/// no-one can see fred directly
};
class B : public A {
public : using A::_fred;
/// but this magically turns A::_fred to be public!
};
int main(int argc, char** argv)
{
B b;
b._fred = 10; // you can do this
return 0;
}
---
[ 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://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Wed, 19 Apr 2006 12:18:10 CST Raw View
philparsonage@hotmail.com wrote:
> OK, so maybe my example wasn't the best, I typed a private instead of a
> protected. The actual code (which compiles using 4.0.2, or 3.3.6) is:
>
> #include <stdlib.h>
>
> class A {
> protected: int _fred;
> /// no-one can see fred directly
> };
>
> class B : public A {
> public : using A::_fred;
> /// but this magically turns A::_fred to be public!
> };
>
> int main(int argc, char** argv)
> {
> B b;
> b._fred = 10; // you can do this
> return 0;
> }
>
This code is fine.
class B derives from class A, and so, is perfectly aware of all
protected members of A.
Thus, it can expose them to everybody.
That's not much different from:
class B : public A {
public : int& fred() {return _fred;}
};
Similarly, using directives can be used to expose privately inherited
members.
class B : private A
public: using A::_fred;
}
Of course, having a public data member in a non-aggregate class, is
usually a sign of bad design... But the point here was the correctness
of data hiding.
The morale here, is that "protected" is nearly equivalent, in terms of
contract, to "public".
A "protected" member is NOT private!
If you write a class with protected members, you make the contract that
you'll not change these members in future...
That is also why, protected data members are a bad idea.
---
[ 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://www.comeaucomputing.com/csc/faq.html ]
Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Thu, 20 Apr 2006 04:02:01 GMT Raw View
philparsonage@hotmail.com ha scritto:
> OK, so maybe my example wasn't the best, I typed a private instead of a
> protected. The actual code (which compiles using 4.0.2, or 3.3.6) is:
>
> #include <stdlib.h>
>
> class A {
> protected: int _fred;
> /// no-one can see fred directly
> };
AHAH! That's *completely* different from the previous example! Notice
that your comment "no-one can see _fred directly" is wrong: classes
derived from A *can* see _fred directly. That's exactly the difference
between private and protected.
> class B : public A {
> public : using A::_fred;
> /// but this magically turns A::_fred to be public!
> };
As B can see _fred directly, it can do whatever it wants, including
making it public. The code is perfectly fine and shows a seldom used but
legal idiom of the using declaration at class scope.
Ganesh
---
[ 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://www.comeaucomputing.com/csc/faq.html ]