Jump to page: 1 2
Thread overview
[Issue 2417] New: protected base member is not available via base hanlde in a derived class if it is defined in a separate module
Oct 13, 2008
d-bugmail
Oct 14, 2008
d-bugmail
Oct 17, 2008
d-bugmail
Oct 17, 2008
d-bugmail
Oct 17, 2008
d-bugmail
Oct 17, 2008
d-bugmail
Oct 17, 2008
d-bugmail
Oct 18, 2008
d-bugmail
Oct 18, 2008
d-bugmail
Oct 18, 2008
d-bugmail
Oct 18, 2008
d-bugmail
[Issue 2417] protected base member is not available via base handle in a derived class if it is defined in a separate module
Nov 24, 2008
d-bugmail
Nov 24, 2008
d-bugmail
[Issue 2417] [module] protected base member is not available via base handle in a derived class if it is defined in a separate module
Jan 23, 2012
Walter Bright
October 13, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417

           Summary: protected base member is not available via base hanlde
                    in a derived class if it is defined in a separate module
           Product: D
           Version: 2.019
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla@digitalmars.com
        ReportedBy: 2korden@gmail.com


The subject says it all, here is a sample:

module m1;
class M1
{
    protected void foo() {}
}

module m2;
import m1;

class M2 : public M1
{
    void bar()
    {
        M1 m1 = new M1();
        m1.foo();         // fails*

        M2 m2 = new M2();
        m2.foo();         // ok
    }
}

* m2.d(9): class m1.M1 member foo is not accessible


-- 

October 14, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417





------- Comment #1 from jarrett.billingsley@gmail.com  2008-10-14 07:51 -------
Good luck convincing Walter on this one.  He refused to budge on it four years ago, citing that "this is the way C++ does it and it must have gotten it right."  I call bullshit on that, but whatever.


-- 

October 17, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417





------- Comment #2 from brunodomedeiros+bugz@gmail.com  2008-10-17 14:14 -------
I also thought this behavior was strange. I checked how Java works, and
surprinsigly, it works the same!
(see http://java.sun.com/docs/books/jls/third_edition/html/names.html#62587 for
a description or
http://java.sun.com/docs/books/jls/third_edition/html/names.html#36191 for an
example)

But I still don't know what is the reason for it. Is there one, or did Java just inherit C++'s mistake?


-- 

October 17, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417





------- Comment #3 from schveiguy@yahoo.com  2008-10-17 14:41 -------
It fails because protected does not give access to outside types that are not of type M2.  the protected attribute is giving access to the derived class ONLY in the case where the instance IS derived to the same type.

i.e.:

class A
{
   protected byte[] getSecretKey() {return null;}
}

// protect B from being overridden, to protect getSecretKey
final class B : A
{
   protected override byte[] getSecretKey()
   {
     // generate a special key that only classes
     // of type B should know
   }
}

class C : A
{
   byte[] backdoor(A a) { return a.getSecretKey(); }
}

Protected is guaranteeing to class B's author that nobody can get at the function except for classes that actually derive from B.


-- 

October 17, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417





------- Comment #4 from jarrett.billingsley@gmail.com  2008-10-17 15:24 -------
When you want to do this, there is no really reasonable way around it.  You make the method protected, subclasses can't call it.  You make it private, no one can call it.  You make it package, only classes at the same level in the package hierarchy can call it.  You make it public, anyone can call it.  There is no good solution.  There is no way to say "this method can be overridden or called from derived classes and nowhere else," which is ostensibly more useful than "this method can only be overridden in derived classes."


-- 

October 17, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417





------- Comment #5 from schveiguy@yahoo.com  2008-10-17 15:43 -------
(In reply to comment #4)
> When you want to do this, there is no really reasonable way around it.  You make the method protected, subclasses can't call it.

Yes they can, they can call it on their own instance, or on instances of the same class.  i.e. the following should work:

if(auto x = cast(M2)m1)
{
   x.foo();
}

> You make it private, no
> one can call it.  You make it package, only classes at the same level in the
> package hierarchy can call it.  You make it public, anyone can call it.  There
> is no good solution.  There is no way to say "this method can be overridden or
> called from derived classes and nowhere else,"

What you are asking for is 'overridden or called from any class that derived from my base class'.  Protected functions already can be called from derived classes in their own instance or in instances of their own type.  Another class may not want you to be able to call their protected function simply by inheriting its base class.

If we listed all the 'protection schemes' that people wanted, I'm sure there would be at least a dozen.  Should all these be implemented?


-- 

October 17, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417





------- Comment #6 from aarti@interia.pl  2008-10-17 16:25 -------
I also think that proposed behavior would be useful. There were few cases where I actually needed such a behavior.

It would be useful e.g. for clone() function, where you have to create new object of specific class, and then setup it before return. You might want to make some properties of this object only changeable for class and its descendant, and in such a case you are stuck... Either you make your properties public or you will not have access to these properties.

It might be something similar as access to private members from same module, which was Walter's experiment, but was fully successful, although no other language implements it.


-- 

October 18, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417





------- Comment #7 from schveiguy@yahoo.com  2008-10-18 10:41 -------
clone does not need a different behavior, this should work:

class C
{
   protected int x;
   C clone()
   {
      auto ret = new C;
      ret.x = x;
      return ret;
   }
}

I don't see the problem.


-- 

October 18, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417





------- Comment #8 from schveiguy@yahoo.com  2008-10-18 10:43 -------
(In reply to comment #7)
> clone does not need a different behavior, this should work:
> 
> class C
> {
>    protected int x;
>    C clone()
>    {
>       auto ret = new C;
>       ret.x = x;
>       return ret;
>    }
> }
> 
> I don't see the problem.
> 

err.. that was a bad example, add this:

class C : D
{
  protected int y;
  D clone()
  {
    auto ret = new D;
    ret.x = x;
    ret.y = y;
  }
}


-- 

October 18, 2008
http://d.puremagic.com/issues/show_bug.cgi?id=2417





------- Comment #9 from schveiguy@yahoo.com  2008-10-18 10:44 -------
(In reply to comment #8)
> err.. that was a bad example, add this:
> 
> class C : D

D'oh!  should have been

class D : C

mind no worky today.


-- 

« First   ‹ Prev
1 2