On Sat, Mar 5, 2011 at 8:15 PM, Marcos Douglas <m...@delfire.net> wrote: > On Sat, Mar 5, 2011 at 7:05 PM, Mark Morgan Lloyd > <markmll.fpc-pas...@telemetry.co.uk> wrote: >> Marcos Douglas wrote: >>> >>> On Sat, Mar 5, 2011 at 8:24 AM, Mark Morgan Lloyd >>> <markmll.fpc-pas...@telemetry.co.uk> wrote: >>>> >>>> Where a unit exports an instance of an object, what's best practice for >>>> making this read-only? I'm referring to the object reference itself here, >>>> not properties of the object. >>>> >>>> Where I've done this in the past I've used a function: >>>> >>>> interface >>>> >>>> function InitText: TFormattedString; >>>> >>>> implementation >>>> >>>> var xInitText: TFormattedString= nil; >>>> >>>> function InitText: TFormattedString; >>>> >>>> begin >>>> result := xInitText >>>> end { InitText } ; >>>> >>>> Is there a better way using e.g. global properties that doesn't >>>> necessitate >>>> both a property and an explicit function? >>>> >>>> property InitText: TFormattedString read xInitText; >>>> >>>> The obvious problem here is that xInitText is a forward reference to an >>>> unexported variable. >>> >>> Make a function to return a global variable does not make it read only. >>> If I use your function like this: >>> o := InitText; >>> o := nil; //this is the same xInitText = nil >> >> Disagree. You are changing the value of o, not of xInitText. xInitText is >> initialised once somewhere in the unit exporting it, subsequently its >> properties etc. can be used elsewhere e.g. InitText.AppendFormatted(...). > > You right... but not TOTALY. > I made a little program to explain that, but now I'm confusing, see: > > program ref; > > {$mode objfpc}{$H+} > > uses > sysutils; > > type > TObj = class > public > i: integer; > end; > > var > o1: TObj = nil; > o2: TObj = nil; > > function getobj: TObj; > begin > if not Assigned(o1) then > o1 := TObj.Create; > o1.i := 1; > result := o1; > end; > > begin > o1 := getobj; > o2 := o1; > writeln('o1.i: ', o1.i); > writeln('o2.i: ', o2.i); > writeln('o2.i change to 2'); > o2.i := 2; > writeln('o1.i = 2 too?": ', o1.i = 2); > writeln('Destroy o2'); > o2.Free; > writeln('o1.i still exists?: ', Assigned(o1), ' so, write o1.i: ', o1.i); > writeln('o1.i change to 3'); > o1.i := 3; > writeln('o1.i: ', o1.i); > try > o1.Free; > except > on e: Exception do > writeln(e.Message); > end; > readln; > end. > > The o1 variable still exists, even after o2 was destroed! But o2 point to > o1... > The variable o1 exists, but I can't destroy it! Why?? > > I test on Lazarus and Delphi 7. > The only diference is in this line: > writeln('o1.i still exists?: ', Assigned(o1), ' so, write o1.i: ', o1.i); > > In Lazarus, the result is: > TRUE | 0 > > In Delphi, the result is: > TRUE | 2 > > Again... Why??
This occurs because I use the "pointer of memory" of property "i" and the compiler ignore the instance of object? I don't understand... if o1==o2 and o1 was released (Free and Nil), why I can continue using o2 if it points to the same memory, i.e., o1? And why I can't destroy it? I think the property "i" continue existing and, because that, I can continue using "i" property through o2 variable. Is that right? Marcos Douglas _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal