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                      ]