Misunderstanding of how PROTECTED works?

General FreeBASIC programming questions.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Misunderstanding of how PROTECTED works?

Post by dodicat »

I get a different result from C++
64 bit g++ version 8.1.0
I declared the functions outside the class (as fb), but tested exactly the same with methods written inside the class.
Thanks Paul Doe for the initial translation.

Code: Select all


class Parent
{
  protected:
    int i ;
    static int j ;
};

int Parent::j = -4 ;

class Child1 : Parent {};

class Child2 : Parent
{
void test( Child2& c2, Parent& p, Child1& c1 );
static void stest( Child2& c2, Parent& p, Child1& c1 );	
};


  void Child2::test( Child2& c2, Parent& p, Child1& c1 )
  {
    // non-static protected member access from non-static member procedure
    i = 1 ;       // OK
    this->i = 2 ; // OK
    c2.i = 3 ;    // OK
    //p.i = 4 ;     // NOK
    //c1.i = 5 ;    // NOK

    // static protected member access from non-static member procedure
    j = 1 ;       // OK
    this->j = 2 ; // OK
    c2.j = 3 ;    // OK
    p.j = 4 ;     // OK
    //c1.j = 5 ;    // NOK
  }

   void Child2::stest( Child2& c2, Parent& p, Child1& c1 )
  {
    // non-static protected member access from static member procedure
    c2.i = 3 ;   // OK
    //p.i = 4 ;    // NOK
    //c1.i = 5 ;   // NOK

    // static protected member access from static member procedure
    j = 1 ;      // OK
    c2.j = 3 ;   // OK
    p.j = 4 ;    // OK
    //c1.j = 5 ;   // NOK
  }
//};

int main()
{
  return 0 ;
} 
paul doe
Moderator
Posts: 1730
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Misunderstanding of how PROTECTED works?

Post by paul doe »

Just to provide another point of view, here's the same code in VB.NET:

Code: Select all

  Private Class Parent
    Protected i As Integer
    Protected Shared j As Integer = 0
  End Class

  Private Class Child1
    Inherits Parent
  End Class

  Private Class Child2
    Inherits Parent

    Public Sub test(c2 As Child2, p As Parent, c1 As Child1)
      ' non-static protected member access from non-static member procedure
      i = 1       ' OK
      Me.i = 2    ' OK
      c2.i = 3    ' OK
      p.i = 4     ' NOK
      c1.i = 5    ' NOK

      ' static protected member access from non-static member procedure
      j = 1       ' OK
      Me.j = 2    ' OK, but not correctly evaluated
      c2.j = 3    ' OK, but not correctly evaluated
      p.j = 4     ' OK, but not correctly evaluated
      c1.j = 5    ' OK, but not correctly evaluated
    End Sub

    Public Shared Sub stest(c2 As Child2, p As Parent, c1 As Child1)
      ' non-static protected member access from static member procedure
      c2.i = 3    ' OK
      p.i = 4     ' NOK
      c1.i = 5    ' NOK

      ' static protected member access from static member procedure
      j = 1       ' OK
      c2.j = 3    ' OK, but not correctly evaluated
      p.j = 4     ' OK, but not correctly evaluated
      c1.j = 5    ' OK, but not correctly evaluated
    End Sub
  End Class
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Misunderstanding of how PROTECTED works?

Post by dodicat »

I did a freepascal one.
private and protected refer to visibility between modules (units)
Whereas freebasic can loose private and protected modes between compiled modules (libraries).
In the same freepascal program private and protected fields can be accessed from anywhere, so OOP in freepascal has a different flavour regarding inheritance.
But I am no great expert at using pascal classes.

Code: Select all

{$mode objfpc}  
{$h+}  
 
Type  
  parent = Class(TObject)
  protected
  i:integer;
  j:integer; static;  
  end;  
  
  child1 = class(parent) 
  end; 
  
  child2 = class(parent)
    class procedure test(c2:child2;p:parent;c1:child1);  
    class Procedure stest(c2:Child2;p:Parent;c1:Child1); static; 
  end; 
 
  
 
Class procedure child2.test(c2:child2;p:parent;c1:child1); 

begin  
// non-static protected member access from non-static member procedure
 
  //I := 1;      
 //self.I := 2;  
 c2.I := 3;    
 p.I := 4 ;   
 c1.I := 5; 
 
 // static protected member access from non-static member procedure
    J := 1 ;
    self.J := 2;
    c2.J := 3;
    p.J := 4;
    c1.J := 5 ;
end;  
 
Class Procedure child2.Stest(c2:Child2;p:Parent;c1:Child1);  
 
begin 
 // non-static protected member access from static member procedure
    c2.I := 3;
    p.I := 4 ;
    c1.I := 5;

    // static protected member access from static member procedure
    J := 1;
    c2.J := 3;
    p.J := 4;
    c1.J := 5 ;  
end; 

begin 
end.

 
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Misunderstanding of how PROTECTED works?

Post by fxm »

For the static protected member data, I omitted the syntaxes of access on typename:

Code: Select all

' FreeBASIC

Type Parent
    Protected:
        Dim As Integer I
        Static As Integer J
End Type
Dim As Integer Parent.J

Type Child1 Extends Parent
End Type

Type Child2 Extends Parent
    Declare Sub test(Byref c2 As Child2, Byref p As Parent, Byref c1 As Child1)
    Declare Static Sub stest(Byref c2 As Child2, Byref p As Parent, Byref c1 As Child1)
End Type

Sub Child2.test(Byref c2 As Child2, Byref p As Parent, Byref c1 As Child1)
    ' non-static protected member access from non-static member procedure
    I = 1        ' OK
    This.I = 2   ' OK
    c2.I = 3     ' OK
    p.I = 4      ' OK
    c1.I = 5     ' OK

    ' static protected member access from non-static member procedure
    J = 1        ' OK
    This.J = 2   ' OK
    c2.J = 3     ' OK
    p.J = 4      ' OK
    c1.J = 5     ' OK
    Child2.J = 6 ' OK
    Parent.J = 7 ' OK
    Child1.J = 8 ' OK
End Sub

Static Sub Child2.stest(Byref c2 As Child2, Byref p As Parent, Byref c1 As Child1)
    ' non-static protected member access from static member procedure
    c2.I = 3     ' OK
    p.I = 4      ' OK
    c1.I = 5     ' OK

    ' static protected member access from static member procedure
    J = 1        ' OK
    c2.J = 3     ' OK
    p.J = 4      ' OK
    c1.J = 5     ' OK
    Child2.J = 6 ' OK
    Parent.J = 7 ' OK
    Child1.J = 8 ' OK
End Sub

marcov
Posts: 3455
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Misunderstanding of how PROTECTED works?

Post by marcov »

dodicat wrote: Apr 21, 2022 22:13 I did a freepascal one.
private and protected refer to visibility between modules (units)
Whereas freebasic can loose private and protected modes between compiled modules (libraries).
In the same freepascal program private and protected fields can be accessed from anywhere, so OOP in freepascal has a different flavour regarding inheritance.
Private: private to class, but accessible within the unit implementing the class
strict private : within the class only, not the rest of the implementing unit.
protected accessible within derivates of the class, but not directly on the instance. and in the unit with the derivative
strict protected: only within derivate itself and not in the derivate's unit
public: publicly available.
published: as public but with RTTI (allowing introspection for streaming) generation.

Whether the protected vs strict protected really matters I'm not 100% sure.

The strict versions were added in D2006+ because too many people with only Java knowledge didn't consider it pure OO enough. I never use them.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Misunderstanding of how PROTECTED works?

Post by dodicat »

C++ for this
Child2::j = 6 ;// OK
Parent::j = 7; // OK
//Child1::j = 8; // NOTOK

[Error] 'int Parent::j' is protected within this context

No problem with freepascal (but not really relevant because the visibility is inter module)
Freebasic seems to keep the rules simple, if the fields and methods of a type (class) are protected, then if a another type (class) extends this type(class) then these protected field/methods are visible from methods in the extending type(class). (or something like that).
C++ has different rules, and there must be a reason for this.
I suppose it becomes important while implementing inheritance in a big project, and there are abundant big projects written in C++.
..
Thank you marcov.

With strict protected the freepascal visibility is almost (not quite) identical to C++ visibility.
coderJeff
Site Admin
Posts: 4313
Joined: Nov 04, 2005 14:23
Location: Ontario, Canada
Contact:

Re: Misunderstanding of how PROTECTED works?

Post by coderJeff »

fxm wrote: Apr 20, 2022 16:39@Jeff and others interested, what is your opinion on the 'Protected' access control definition ?
As dodicat points rules are rather simple.

private: visible within the class
public: visible outside the class
protected: visible to *any* derived class

A little graph of the original may help:

Code: Select all

           object
             |
           widget (X,Y)
          /      \
container (B)     button (C)
                             - method()
How it works now:
- 'button' knows about widget's protected X,Y members
- Both 'button' and 'container' are derived from 'widget' so widget's protected X,Y members are accessible within the context of 'button,method' (even if accessed through a 'container' pointer)


Sounds like what is discussed (based on this example):
- is maybe something like a 'private protected' visibility
- that in the context of 'button', widget's protected X,Y members are NOT accessible through container pointer
- however, widget's protected X, Y members would still be accessible anyway through polymorphism, but we require an extra step to access container through a base class

Code: Select all

sub button.method( c as container ptr )
dim w as widget ptr = c
? w->X, w->Y
end sub
My overall opinion is that rules could become much more complicated both to implement and to use and still not satisfy everyone.
marcov
Posts: 3455
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: Misunderstanding of how PROTECTED works?

Post by marcov »

dodicat wrote: Apr 22, 2022 11:30 No problem with freepascal (but not really relevant because the visibility is inter module)
Other languages often have friend class as something equivalent (as the per module access is quite often used when multiple classes are defined within one module). Not a must per se, more something to keep in mind.

I have a quite dim view of visibility, and often get tired of the endless discussions about it. If you want to implement all users requests wrt visibility, might I suggest to start with a baseline of adding an ACL to each identifier :lol:
Post Reply