www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Frustrated by 'protected' again

reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
I posted this a while ago, but the problem still has not been addressed. 
Mostly because Walter doesn't think it's a problem.

[file1.d]

class A
{
    protected int x;
}

[file2.d]

import file1;

class B : A
{
    void fork()
    {
        x = 5; // OK

        B b = new B;
        b. x = 8;  // OK

        A a = new A;
        a.x = 10; // Not OK, and frustrating
    }
}


Walter says that "this is the way C++ does it."  I don't care.  D is not 
C++, and this is just as frustrating in C++ as it is in D.  If B is declared 
in the same file as A, it's legal, but this way, it's not.  This makes it 
very difficult to extend classes in modules separate from the module in 
which the base class was declared.

And no, it can't be made public.  That completely defeats the purpose of 
protection attributes.

All I want to know is the single, overriding rationale for keeping the 
behavior like this.  "It's the way C++ does it" is not good enough. 
Dec 18 2005
next sibling parent reply Sean Kelly <sean f4.ca> writes:
Jarrett Billingsley wrote:
 I posted this a while ago, but the problem still has not been addressed. 
 Mostly because Walter doesn't think it's a problem.
 
 [file1.d]
 
 class A
 {
     protected int x;
 }
 
 [file2.d]
 
 import file1;
 
 class B : A
 {
     void fork()
     {
         x = 5; // OK
 
         B b = new B;
         b. x = 8;  // OK
 
         A a = new A;
         a.x = 10; // Not OK, and frustrating
     }
 }
 
 
 Walter says that "this is the way C++ does it."  I don't care.  D is not 
 C++, and this is just as frustrating in C++ as it is in D.  If B is declared 
 in the same file as A, it's legal, but this way, it's not.  This makes it 
 very difficult to extend classes in modules separate from the module in 
 which the base class was declared.

I thought "protected" class members were only visible to deriving classes, why is a.x visible if B is declared in the same module as A?
 And no, it can't be made public.  That completely defeats the purpose of 
 protection attributes.
 
 All I want to know is the single, overriding rationale for keeping the 
 behavior like this.  "It's the way C++ does it" is not good enough. 

This is a somewhat weird aspect of inheritance. Basically, at all times, all a class can ever see are its own data members. It just so happens that in this case, some of B's data members were imported from A. The important distinction here is that B can only access this data *within the context of B*. To do otherwise would break protection rules. From your example, why should B have access to the protected innards of all A's just because B extends A? Sean
Dec 18 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Sean Kelly" <sean f4.ca> wrote in message 
news:do4rsd$h0f$1 digitaldaemon.com...
 This is a somewhat weird aspect of inheritance.  Basically, at all times, 
 all a class can ever see are its own data members.  It just so happens 
 that in this case, some of B's data members were imported from A.  The 
 important distinction here is that B can only access this data *within the 
 context of B*.  To do otherwise would break protection rules.  From your 
 example, why should B have access to the protected innards of all A's just 
 because B extends A?

Why should classes be able to access members of other classes defined in the same module, regardless of protection attributes? Because it's useful. That "breaks" protection rules too, but no one complains about that. In the same way, allowing access to protected members of base classes through base class references is useful. All I want to know is the _downside_ of allowing this.
Dec 18 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Sun, 18 Dec 2005 18:50:43 -0500, Jarrett Billingsley wrote:

 "Sean Kelly" <sean f4.ca> wrote in message 
 news:do4rsd$h0f$1 digitaldaemon.com...
 This is a somewhat weird aspect of inheritance.  Basically, at all times, 
 all a class can ever see are its own data members.  It just so happens 
 that in this case, some of B's data members were imported from A.  The 
 important distinction here is that B can only access this data *within the 
 context of B*.  To do otherwise would break protection rules.  From your 
 example, why should B have access to the protected innards of all A's just 
 because B extends A?

Why should classes be able to access members of other classes defined in the same module, regardless of protection attributes? Because it's useful. That "breaks" protection rules too, but no one complains about that.

Sort of ... but the assumption is that things defined in the same module (source file) are 'friends' of each other. So, the same person that maintains one class also will be capable of maintaining the other classes in the same file. In this way, the 'module' scoping overrides all other scopes (but maybe not inner classes?).
  In the 
 same way, allowing access to protected members of base classes through base 
 class references is useful.  

Can you give us an example? And could be done in other ways? For example ... //---------------- import file1; // Use 'Base_A' to gain simple access to base class members. class Base_A : A { } class B : A { void fork() { x = 5; // OK B b = new B; b. x = 8; // OK Base_A a = new Base_A; // Not 'new A'; a.x = 10; // Now OK } }
 All I want to know is the _downside_ of allowing this.

It weakens the concept of protected. In the 'workaround' above at least it explicitly documents what I'm trying to do. -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 19/12/2005 12:01:32 PM
Dec 18 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:9bezpukt519x.152h73q6j874i.dlg 40tude.net...
 Sort of ... but the assumption is that things defined in the same module
 (source file) are 'friends' of each other. So, the same person that
 maintains one class also will be capable of maintaining the other classes
 in the same file. In this way, the 'module' scoping overrides all other
 scopes (but maybe not inner classes?).

Right. (Although I think the thing with inner classes is just a bug.)
 Can you give us an example? And could be done in other ways?

Your example works, but not necessarily for all situations. Like: [file1.d] module file1; private import std.stdio; class A { this(int i) { x = i; } void something() { as.length = 5; for(uint i = 0; i < 5; i++) as[i] = new A(i + 1); } void printChildren() { foreach(A a; as) writefln(a.x); } protected A[] as; protected int x; } [file2.d] module file2; import std.stdio; import file1; class B : A { this(int i) { super(i); } override void printChildren() { foreach(A a; as) writefln("From B: ", a.x); // No good } } void main(char[][] args) { A a = new A(0); a.something(); a.printChildren(); B b = new B(0); b.something(); b.printChildren(); } In many of my projects, I run into similar situations - needing to override a function in a subclass which needs to access members of base class references. And in many of my projects, I run into the same limitation. Most of the time, I can't just call the super.overriddenFunction(), because I'm changing the internal workings of the function.
 It weakens the concept of protected. In the 'workaround' above at least it
 explicitly documents what I'm trying to do.

I think saying that the class inherits from another class does that just fine. Personally I think that being able to access members of base class references seems perfectly normal, and I don't see how it "weakens" protected. It makes it better, if anything.
Dec 18 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Sun, 18 Dec 2005 21:34:02 -0500, Jarrett Billingsley  
<kb3ctd2 yahoo.com> wrote:
 "Derek Parnell" <derek psych.ward> wrote in message
 news:9bezpukt519x.152h73q6j874i.dlg 40tude.net...
 Sort of ... but the assumption is that things defined in the same module
 (source file) are 'friends' of each other. So, the same person that
 maintains one class also will be capable of maintaining the other  
 classes
 in the same file. In this way, the 'module' scoping overrides all other
 scopes (but maybe not inner classes?).

Right. (Although I think the thing with inner classes is just a bug.)
 Can you give us an example? And could be done in other ways?

Your example works, but not necessarily for all situations. Like: [file1.d] module file1; private import std.stdio; class A { this(int i) { x = i; } void something() { as.length = 5; for(uint i = 0; i < 5; i++) as[i] = new A(i + 1); } void printChildren() { foreach(A a; as) writefln(a.x); } protected A[] as; protected int x; } [file2.d] module file2; import std.stdio; import file1; class B : A { this(int i) { super(i); } override void printChildren() { foreach(A a; as) writefln("From B: ", a.x); // No good } } void main(char[][] args) { A a = new A(0); a.something(); a.printChildren(); B b = new B(0); b.something(); b.printChildren(); } In many of my projects, I run into similar situations - needing to override a function in a subclass which needs to access members of base class references. And in many of my projects, I run into the same limitation. Most of the time, I can't just call the super.overriddenFunction(), because I'm changing the internal workings of the function.
 It weakens the concept of protected. In the 'workaround' above at least  
 it
 explicitly documents what I'm trying to do.

I think saying that the class inherits from another class does that just fine. Personally I think that being able to access members of base class references seems perfectly normal, and I don't see how it "weakens" protected. It makes it better, if anything.

It "weakens" in the sense that it lessens the protection that protected gives. Your suggested change would allow an instance of a B to access "protected" members of _another_ instance of an A or B. Typically to get that access you make them "friends" i.e. put them in the same module, perhaps there is room for another protection type, but I don't think we want to modify protected. Regan
Dec 18 2005
parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Regan Heath wrote:
[...]
 It "weakens" in the sense that it lessens the protection that
 protected  gives.

Isn't the protection `protected' gives already too low? According to the specs it is the duty of every class to defend its `invariant' for every instantiation. This defending cannot be done in general, if other entities have write access to members of the class without using a function of the class. Therefore all write accesses to members of classes must be forbidden or the definition of what an `invariant' is, must be dropped. -manfred
Dec 19 2005
parent reply Tom <Tom_member pathlink.com> writes:
I agree, this is unavoidable.

In article <Xns9731EECD4CC86svv1999hotmailcom 63.105.9.61>, Manfred Nowak
says...
Regan Heath wrote:
[...]
 It "weakens" in the sense that it lessens the protection that
 protected  gives.

Isn't the protection `protected' gives already too low? According to the specs it is the duty of every class to defend its `invariant' for every instantiation. This defending cannot be done in general, if other entities have write access to members of the class without using a function of the class. Therefore all write accesses to members of classes must be forbidden or the definition of what an `invariant' is, must be dropped.

Tom
Dec 19 2005
parent Manfred Nowak <svv1999 hotmail.com> writes:
Tom wrote:

 I agree, this is unavoidable.

Thanks for your affirmative answer, but my conclusion seems to be at least partly wrong. If a class declares a member to be `protected' although it is a vital member of its invariant, then the definition of the class is faulty. Maybe the language should change the names of its protection attributes to represent the impact of the protection attribute instead of the abstract description of the effect: `invariable' instead of `private' `inheretable' instead of `protected' `unprotected' instad of `public' According to the absence of protectection of invariants in modules, this seems to propose a maintenance disaster, because it is based on easying the coding and not the maintenenance. Every maintainer wants to be sure to not destroy accidentically an invariant of a class. But how can a maintainer do that without knowing the details of the implementaions of every invariant of the module she/he is working on, in case of the current specs, where every coder is allowed to distribute the components defending the invariants all over a module. On the other hand I do not see, how to make those components easily locatable. -manfred
Dec 19 2005
prev sibling parent Derek Parnell <derek psych.ward> writes:
On Sun, 18 Dec 2005 21:34:02 -0500, Jarrett Billingsley wrote:

 "Derek Parnell" <derek psych.ward> wrote in message 

[snip]
 In many of my projects, I run into similar situations - needing to override 
 a function in a subclass which needs to access members of base class 
 references.  And in many of my projects, I run into the same limitation. 
 Most of the time, I can't just call the super.overriddenFunction(), because 
 I'm changing the internal workings of the function.

I see now. If the access you want is read-only then you can document and use that explicitly. In your example add the these two methods to class A ... int ro_x() {return x;} A onApply(int i){return as[i];} and change the overriding function in B to say ... writefln("From B: ", a.ro_x); That way, the stuff in A is still runtime protected, and B (and others) can access the data in a safer read-only way.
 It weakens the concept of protected. In the 'workaround' above at least it
 explicitly documents what I'm trying to do.

I think saying that the class inherits from another class does that just fine. Personally I think that being able to access members of base class references seems perfectly normal, and I don't see how it "weakens" protected. It makes it better, if anything.

We differ. -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 19/12/2005 4:36:14 PM
Dec 18 2005
prev sibling parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
Jarrett Billingsley wrote:
 "Sean Kelly" <sean f4.ca> wrote in message 
 news:do4rsd$h0f$1 digitaldaemon.com...
 
This is a somewhat weird aspect of inheritance.  Basically, at all times, 
all a class can ever see are its own data members.  It just so happens 
that in this case, some of B's data members were imported from A.  The 
important distinction here is that B can only access this data *within the 
context of B*.  To do otherwise would break protection rules.  From your 
example, why should B have access to the protected innards of all A's just 
because B extends A?

Why should classes be able to access members of other classes defined in the same module, regardless of protection attributes? Because it's useful. That "breaks" protection rules too, but no one complains about that.

I do complain about that! Some others complain too, but it doesn't seem like Walter is gonna change it.
Dec 18 2005
prev sibling next sibling parent reply Ant <Ant_member pathlink.com> writes:
In article <do4qi9$eam$1 digitaldaemon.com>, Jarrett Billingsley says...
I posted this a while ago, but the problem still has not been addressed. 
Mostly because Walter doesn't think it's a problem.

[file1.d]

class A
{
    protected int x;
}

[file2.d]

import file1;

class B : A
{
    void fork()
    {
        x = 5; // OK

        B b = new B;
        b. x = 8;  // OK

        A a = new A;
        a.x = 10; // Not OK, and frustrating
    }
}

Actually this is rigth. You don't have access to the protected members of an object you own. b.x is visible on b because B extendes A. a.x is NOT visible because x is protected on A. You need to review your design. Walter doesn't need to do anything. Ant
Dec 19 2005
parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Ant wrote:
 Actually this is rigth.
 You don't have access to the protected members of an object you own.
 
 b.x is visible on b because B extendes A.
 a.x is NOT visible because x is protected on A.

Maybe I'm missing something, but I've always understood the typical protection attributes to mean: public = anybody can see it private = only this class/object can see it protected = only this class/object *and its descendants* can see it So shouldn't a child class be able to see its parent's protected members? That's supposed to be the whole idea. If I wanted it hidden completely, I'd use private, yes? Or do I misunderstand his issue? -- Chris Sauls
Dec 19 2005
next sibling parent reply Ant <Ant_member pathlink.com> writes:
In article <do77p6$1le0$1 digitaldaemon.com>, Chris Sauls says...
Ant wrote:
 Actually this is rigth.
 You don't have access to the protected members of an object you own.
 
 b.x is visible on b because B extendes A.
 a.x is NOT visible because x is protected on A.

Maybe I'm missing something, but I've always understood the typical protection attributes to mean: public = anybody can see it private = only this class/object can see it protected = only this class/object *and its descendants* can see it So shouldn't a child class be able to see its parent's protected members? That's supposed to be the whole idea. If I wanted it hidden completely, I'd use private, yes? Or do I misunderstand his issue? -- Chris Sauls

You misunderstood. in this case 'a' is a different object, 'a' it's not the "this" object. beeing a different object the protected access modifier doesn't allow you to access the element. "That's supposed to be the whole idea." ;) (java makes protected elements visible through the entire package - or something like don't remember clearly now. java also has the "package" access - that's the default access there is no keyword for it) anyway when I first read the original post I thought "Walter screw it again" but no, this time he is right. Other times you are wrong, Walter... Ant
Dec 19 2005
parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Ant wrote:
 In article <do77p6$1le0$1 digitaldaemon.com>, Chris Sauls says...
 
Ant wrote:

Actually this is rigth.
You don't have access to the protected members of an object you own.

b.x is visible on b because B extendes A.
a.x is NOT visible because x is protected on A.

Maybe I'm missing something, but I've always understood the typical protection attributes to mean: public = anybody can see it private = only this class/object can see it protected = only this class/object *and its descendants* can see it So shouldn't a child class be able to see its parent's protected members? That's supposed to be the whole idea. If I wanted it hidden completely, I'd use private, yes? Or do I misunderstand his issue? -- Chris Sauls

You misunderstood. in this case 'a' is a different object, 'a' it's not the "this" object. beeing a different object the protected access modifier doesn't allow you to access the element.

But 'b' is a *descendant of* 'a' (aka, subclass) so 'protected' members are supposed to be visible! It sounds like you really want 'private' behavior here?? -- Chris Sauls
Dec 19 2005
parent Mike Parker <aldacron71 yahoo.com> writes:
Chris Sauls wrote:
 Ant wrote:

 But 'b' is a *descendant of* 'a' (aka, subclass) so 'protected' members 
 are supposed to be visible!  It sounds like you really want 'private' 
 behavior here??

No. The *class* B is a descendant of the *class* A, but the *instance* b has no relationship with the *instance* of a. b should *not* be able to access the protected members of any instance of A, only that of its super instance (i.e. that which is part of its own memory space). It will have access to the protected members of any instance of B. And if you cast it to an A it will then have access to the protected members of any instance of A - because then it is not a B anymore but an A.
Dec 20 2005
prev sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Chris Sauls wrote:

[...]
 Maybe I'm missing something, but I've always understood the
 typical protection attributes to mean:
 public = anybody can see it
 private = only this class/object can see it
 protected = only this class/object *and its descendants* can see
 it 

From the specs you are right, because they state, that every descendant _class_ can see the protected members of its father _class_. But this seems to be nonsense, because in fact only instances of classes can control something at runtime and if an instance of a class can conrol the members of any other instance of this class, the instance of the class with members controlled would loose its autonomy, especially its role to shield its data. Therefore the specs should state, that every "instance of a descendant class" can see the protected members of the "instance of its father class" only. -manfred
Dec 19 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 20 Dec 2005 05:13:49 +0000 (UTC), Manfred Nowak wrote:


 From the specs you are right, because they state, ...

 But this seems to be nonsense, because in fact ...

 Therefore the specs should state, that ...

Walter, I don't want to sound impertinent, so please take this in the friendly manner it was meant. In the grand scheme of all things D, is getting the specification documented correctly more or less important than getting the implementation (a.k.a DMD) right? My POV is that the specs should be settled prior to finalizing the implementation. -- Derek (skype: derek.j.parnell) Melbourne, Australia 20/12/2005 4:28:57 PM
Dec 19 2005
parent reply "Walter Bright" <newshound digitalmars.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:1ql9ydrigronc.1jzq1rh9e2ry0$.dlg 40tude.net...
 In the grand scheme of all things D, is getting the specification
 documented correctly more or less important than getting the 
 implementation
 (a.k.a DMD) right?

Right.
 My POV is that the specs should be settled prior to finalizing the
 implementation.

Right - and for the protected case, it should work like the C++ model.
Dec 21 2005
next sibling parent reply Dawid =?UTF-8?B?Q2nEmcW8YXJraWV3aWN6?= <dawid.ciezarkiewicz gmail.com> writes:
Walter Bright wrote:
 My POV is that the specs should be settled prior to finalizing the
 implementation.

Right - and for the protected case, it should work like the C++ model.

I've got a question. (if I may :) ) From specs: "The class invariant is a contract saying that the asserts must hold true. The invariant is checked when a class constructor completes, at the start of the class destructor, before a public or exported member is run, and after a public or exported function finishes." D implements C++'s model of protection. That is, the following is legal: class B { invariant { assert(x < 3); } private: int x; public: void bla(B b) { b.x = 4; // we can operate on private members // of some totally other instance } }; The point is, invariants are to ensure instantion is never "broken". But using fact, that one object can operate internaly on other because they are from same class can lead to situation that one instantion will "break" other and that fact will go undetected (no public member was called). The fact of "broken instantion" will problably be detected in some other place but this can be a) confusing b) happens in some critical section. Do you think this is a kind of issue?
Dec 21 2005
parent reply Bruno Medeiros <daiphoenixNO SPAMlycos.com> writes:
Dawid Ciężarkiewicz wrote:
 Walter Bright wrote:
 
My POV is that the specs should be settled prior to finalizing the
implementation.

Right - and for the protected case, it should work like the C++ model.

I've got a question. (if I may :) ) From specs: "The class invariant is a contract saying that the asserts must hold true. The invariant is checked when a class constructor completes, at the start of the class destructor, before a public or exported member is run, and after a public or exported function finishes." D implements C++'s model of protection. That is, the following is legal: class B { invariant { assert(x < 3); } private: int x; public: void bla(B b) { b.x = 4; // we can operate on private members // of some totally other instance } }; The point is, invariants are to ensure instantion is never "broken". But using fact, that one object can operate internaly on other because they are from same class can lead to situation that one instantion will "break" other and that fact will go undetected (no public member was called). The fact of "broken instantion" will problably be detected in some other place but this can be a) confusing b) happens in some critical section. Do you think this is a kind of issue?

Hum, very good point. Seems to me that if we can't access protected members of other same-class instances, we shouldn't also be able to access private members of other same-class instances. (also because of consistency, not just because of the invariant issue you mentioned) -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Dec 21 2005
next sibling parent Dawid =?UTF-8?B?Q2nEmcW8YXJraWV3aWN6?= <dawid.ciezarkiewicz gmail.com> writes:
Bruno Medeiros wrote:

 Dawid Ciężarkiewicz wrote:
 Walter Bright wrote:
 
My POV is that the specs should be settled prior to finalizing the
implementation.

Right - and for the protected case, it should work like the C++ model.

I've got a question. (if I may :) ) From specs: "The class invariant is a contract saying that the asserts must hold true. The invariant is checked when a class constructor completes, at the start of the class destructor, before a public or exported member is run, and after a public or exported function finishes." D implements C++'s model of protection. That is, the following is legal: class B { invariant { assert(x < 3); } private: int x; public: void bla(B b) { b.x = 4; // we can operate on private members // of some totally other instance } }; The point is, invariants are to ensure instantion is never "broken". But using fact, that one object can operate internaly on other because they are from same class can lead to situation that one instantion will "break" other and that fact will go undetected (no public member was called). The fact of "broken instantion" will problably be detected in some other place but this can be a) confusing b) happens in some critical section. Do you think this is a kind of issue?

Hum, very good point. Seems to me that if we can't access protected members of other same-class instances, we shouldn't also be able to access private members of other same-class instances. (also because of consistency, not just because of the invariant issue you mentioned)

I hope this issue will get attention and will be discussed further. I can easily imagine situations when class will need methods that other instances could operate on but shouldn't be available to public. Such methods should be protected by invariant but not be public. Idealy there would be one more keyword ("public", "protected", "private" and ... "multiinstance" maybe) that will do the deal. In such model class could operate only on "this" pointer AND on public and multinstance methods of pointers from same (or parent) class. But this would be big change and this is only free idea.
Dec 21 2005
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 21 Dec 2005 16:55:35 +0000, Bruno Medeiros wrote:


[snip]
 
 Seems to me that if we can't access protected 
 members of other same-class instances, we shouldn't also be able to 
 access private members of other same-class instances. (also because of 
 consistency, not just because of the invariant issue you mentioned)

Is there need to consider read and write accesses differently? For it may be okay to have read access to parent class data but not write access. -- Derek Parnell Melbourne, Australia 22/12/2005 7:51:48 AM
Dec 21 2005
parent Manfred Nowak <svv1999 hotmail.com> writes:
Derek Parnell wrote:

[...]
 Is there need to consider read and write accesses differently?
 For it may be okay to have read access to parent class data but
 not write access. 

Yes. Because as already stated, write accesses may destroy an invariant of that instantiation. It is a fiction to believe that all invariants of all instances are the same, because the invariant more or less formally defined for a class may be the minimal invariant shared by all instances. And the specs do not guarantee optimizing out a definition of a class whose sole purpose is to sharpen the invariant of its super class. -manfred
Dec 21 2005
prev sibling parent Manfred Nowak <svv1999 hotmail.com> writes:
Walter Bright wrote:

[...]
 My POV is that the specs should be settled prior to finalizing
 the implementation.

Right - and for the protected case, it should work like the C++ model.

But C++ does not have a model for `protected' in conjunction with `package' or `export'. In the D-specs the protection attribute `protected' is even left out from the possibilities of protection for the super class and the interfaces. -manfred
Dec 21 2005
prev sibling next sibling parent reply Dawid =?UTF-8?B?Q2nEmcW8YXJraWV3aWN6?= <dawid.ciezarkiewicz gmail.com> writes:
Manfred Nowak wrote:
 Chris Sauls wrote:
 
 [...]
 Maybe I'm missing something, but I've always understood the
 typical protection attributes to mean:
 public = anybody can see it
 private = only this class/object can see it
 protected = only this class/object *and its descendants* can see
 it

From the specs you are right, because they state, that every descendant _class_ can see the protected members of its father _class_. But this seems to be nonsense, because in fact only instances of classes can control something at runtime and if an instance of a class can conrol the members of any other instance of this class, the instance of the class with members controlled would loose its autonomy, especially its role to shield its data.

There are two kind of protection. Class- and object- protection. In C++ there is a class-protection implemented and I used this fact from time to time. Current D spec seems to use class-protection but implementation behaves like object-protection. I do not wish to advocate, but class-protection isn't nonsense. Each instance of class is same as other instances. So it can operate on them because it know how not to hurt them. Actualy I think in D object-protection should be used because of invariants and other well designed things in D. The specification is just wrong, happens.
Dec 20 2005
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Dawid Ciezarkiewicz" <dawid.ciezarkiewicz gmail.com> wrote in message 
news:do9fbb$1hqq$1 digitaldaemon.com...
 Each instance of class is same as other
 instances. So it can operate on them because it know how not to hurt them.

Yes! That's it. A descendant class knows about its parent class, so it should be able to mess with protected members of parent class references because it knows what to do.
Dec 21 2005
prev sibling parent =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
Manfred Nowak wrote:
 Chris Sauls wrote:
 
 [...]
 
Maybe I'm missing something, but I've always understood the
typical protection attributes to mean:
public = anybody can see it
private = only this class/object can see it
protected = only this class/object *and its descendants* can see
it 

[...] From the specs you are right, because they state, that every descendant _class_ can see the protected members of its father _class_. But this seems to be nonsense, because in fact only instances of classes can control something at runtime and if an instance of a class can conrol the members of any other instance of this class, the instance of the class with members controlled would loose its autonomy, especially its role to shield its data. Therefore the specs should state, that every "instance of a descendant class" can see the protected members of the "instance of its father class" only.

But isn't the "instance of its father class" the same as "instance of a descendant class". Of course there's some polymorphism between them, but I think these refer to the same object. Should it be something like "the instance of a descendant class recursively inherits the protected members of the father class, but is not allowed to access protected members of other classes unless they are 'friends' (in the same module)".
Dec 20 2005
prev sibling parent Manfred Nowak <svv1999 hotmail.com> writes:
Jarrett Billingsley wrote:

[...]
         B b = new B;
         b. x = 8;  // OK

It is not OK, that this is okay in any case. At least it is inconsistent, that the assignment (cast(A) b).x= 8; // not OK is not allowed. -manfred [X-posted to D.bugs, F'up staying in D]
Dec 21 2005