Topic: Protected when composing


Author: nospam@yahoo.com.ar ("David A. Caabeiro")
Date: Tue, 26 Nov 2002 22:41:43 +0000 (UTC)
Raw View
> I think one thing that confused the issue on the private mail list
> (accu-general, for those keeping score) was the overloading of the

accu-prog-questions actually...

> "protected" keyword. As presented, this idea would be a major loophole
> in encapsulation.

Yes, that's something I forgot to mention here, sorry. In my original post
I noted the necessity of using a different keyword, as using 'protected'
would break current code.

> For purposes of this discussion, it might be better to use a different
> keyword to get across the idea, perhaps "composite". The final example
> then becomes:
>
> class bar
> {
> composite:
>    int b;
> };
>
> class foo
> {
>    bar B;
> public:
>    foo() { B.b = 0; } // OK.
> };
>
> Now, I think the intent becomes clearer: 'b' is accessible *only* to
> classes which use class bar via composition.
>
> Mind you, now that I think about it, you can get the same effect using
> private inheritance:

Yes, Jon Jagger provided a similar example when this was discussed in
the private list. The thing is that -while "syntactically" equivalent- I
think in certain cases the use of composition would fit better (ie. would
make the code clearer) in lieu of inheritance.

Regards,
David.



---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 28 Nov 2002 03:07:37 +0000 (UTC)
Raw View
> David A. Caabeiro wrote:
> > wouldn't it be practical to allow in certain cases (in this case
> > composition, not inheritance) to allow a class to handle one of its
> > components private members, but do not allow this to external classes?

> > class bar {
> > protected: // Or some other keyword
> >   int b;
> > };
> >
> > class foo {
> > public:
> >   foo() { B.b = 0; }  // this should be OK (currently it's not allowed)
> > private:
> >   bar B;
> > };

jhyslop@ieee.org (Jim Hyslop) wrote
> For purposes of this discussion, it might be better to use a different
> keyword to get across the idea, perhaps "composite". The final example
> then becomes:
>
> class bar
> {
> composite:
>    int b;
> };
>
> class foo
> {
>    bar B;
> public:
>    foo() { B.b = 0; } // OK.
> };
>
> Now, I think the intent becomes clearer: 'b' is accessible *only* to
> classes which use class bar via composition.

David and Jim very clearly stated WHAT they wanted. I'm sorry, but I
don't quite get WHY you want it.

> Mind you, now that I think about it, you can get the same effect using
> private inheritance:
>
> class bar
> {
> protected:
>     int i;
> };
>
> class foo : private bar
> {
> public:
>    foo() { bar::i = 0; } // Allowed under current rules.
> };

Which won't work if you want to use multiple BAR objects.
    class foo {
        bar B[5]; // Want access to all of the b's.
        // ...
    };

> // Or, to avoid potential multiple inheritance issues:
> class barExposer
> {
> public:
>     int &getI() { return i; }
> };
>
> class foo
> {
>    barExposer b;
> public:
>    foo() { b.getI() = 0; } // OK.
> };

I think a better way would be to grant foo the right to read the b.

Method #1 -- friendship. If foo really needs to get into the bar, make
it a friend. That's what friend was invented for!

Method #2 -- better encapsulation.
    class foo {
        struct bar {
            // Doesn't need to be protected, now!
            int b;
        } B;
    public:
        foo() { B.b = 0; }
    };
Since class foo::bar is private to class foo, you need not fear that
any other code will mess with it's data.

If you would still prefer to have the composite-versus-protected
concept, would you please explain why? Maybe show us some code where
it would be used, where one of these other techniques wouldn't work
just as well?

Thanks.

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jhyslop@ieee.org (Jim Hyslop)
Date: Tue, 26 Nov 2002 07:31:28 +0000 (UTC)
Raw View
David A. Caabeiro wrote:
[...]
> So you, as the author of bar, are stating that b should be private
> *except* when inheriting publicly. In this case, you allow the derived
> class to handle bar's private members.
>
> So this is the 'extension' I was thinking of. In a similar way as shown
> above, wouldn't it be practical to allow in certain cases (in this case
> composition, not inheritance) to allow a class to handle one of its
> components private members, but do not allow this to external classes?
>
[...]
> But if you state this:
>
> class bar {
> protected:
>   int b;
> };
>
> class foo {
> public:
>   foo() { B.b = 0; }  // this should be OK (currently it's not allowed)
> private:
>   bar B;
> };
I think one thing that confused the issue on the private mail list
(accu-general, for those keeping score) was the overloading of the
"protected" keyword. As presented, this idea would be a major loophole
in encapsulation.

For purposes of this discussion, it might be better to use a different
keyword to get across the idea, perhaps "composite". The final example
then becomes:

class bar
{
composite:
   int b;
};

class foo
{
   bar B;
public:
   foo() { B.b = 0; } // OK.
};

Now, I think the intent becomes clearer: 'b' is accessible *only* to
classes which use class bar via composition.

Mind you, now that I think about it, you can get the same effect using
private inheritance:

class bar
{
protected:
    int i;
};

class foo : private bar
{
public:
   foo() { bar::i = 0; } // Allowed under current rules.
};

// Or, to avoid potential multiple inheritance issues:
class barExposer
{
public:
    int &getI() { return i; }
};

class foo
{
   barExposer b;
public:
   foo() { b.getI() = 0; } // OK.
};

--
Jim

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Tue, 26 Nov 2002 15:49:25 +0000 (UTC)
Raw View
In article <3DE2ED22.6040700@ieee.org>, Jim Hyslop <jhyslop@ieee.org>
writes
>> But if you state this:
>>  class bar {
>> protected:
>>   int b;
>> };
>>  class foo {
>> public:
>>   foo() { B.b = 0; }  // this should be OK (currently it's not allowed)
>> private:
>>   bar B;
>> };
>I think one thing that confused the issue on the private mail list
>(accu-general, for those keeping score) was the overloading of the
>"protected" keyword. As presented, this idea would be a major loophole
>in encapsulation.


I think it might make sense to add the underlying idea/motivation to the
block of ideas being considered by the evolution working group on how to
better manage issues that surround private inheritance, inheritance of
implementation and composition. I think Lois Goldthwaite is the guardian
of these issues.


--
Francis Glassborow      ACCU
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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: nospam@yahoo.com.ar ("David A. Caabeiro")
Date: Mon, 25 Nov 2002 18:27:19 +0000 (UTC)
Raw View
Some days ago I posted this in a closed list, and got some responses,
so I'd like to know about your oppinions and thoughts.

Consider this,

1) Current behaviour

class bar {
  int b;           // b is private everywhere
};

class foo {
public:
  foo() { B.b = 0; }  // this is not allowed because
                               // b is private
private:
  bar B;
};


With inheritance, you have the following situation:

class bar {
  int b;           // b is private everywhere
};

class foo : public bar {
public:
  foo() { b = 0; } // error because b is private
};

But if declare bar member as protected:

class bar {
protected:
  int b;           // b is private only for alien classes
};

class foo : public bar {
public:
  foo() { b = 0; } // OK because b is protected
};

So you, as the author of bar, are stating that b should be private
*except* when inheriting publicly. In this case, you allow the derived
class to handle bar's private members.

So this is the 'extension' I was thinking of. In a similar way as shown
above, wouldn't it be practical to allow in certain cases (in this case
composition, not inheritance) to allow a class to handle one of its
components private members, but do not allow this to external classes?

So, if you have:

class bar {
private:
  int b;
};

class foo {
public:
  foo() { B.b = 0; }  // this is error
private:
  bar B;
};

But if you state this:

class bar {
protected:
  int b;
};

class foo {
public:
  foo() { B.b = 0; }  // this should be OK (currently it's not allowed)
private:
  bar B;
};


So even if you do this:

class bar {
protected:
  int b;
};

class foo {
public:
  foo() { B.b = 0; }  // this is OK
  bar B;  // note B is also public
};

But this is not:

foo F;
F.B.b = 1;

and neither this:

bar BB;
BB.b = 0;

Hope I made this clear enough...

Regards,
David.




---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]