AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Properties haben nach Zuweisung falsche Werte

Ein Thema von BlueStarHH · begonnen am 29. Okt 2014 · letzter Beitrag vom 31. Okt 2014
Antwort Antwort
Seite 4 von 5   « Erste     234 5      
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hannover-Hainholz
801 Beiträge
 
Delphi 11 Alexandria
 
#31

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 17:06
@Der schöne Günther: Dein Code ist eine gute Zusammenfassung und zeigt mit Delphi 2010 den Fehler. Stellt das jemand bitte in den QC ein? Ich kann mich seit 20 Minuten nicht einloggen... Danke!
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.009 Beiträge
 
Delphi 12 Athens
 
#32

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 17:08
Wäre es denn im konkreten Fall nicht besser, das ganze Konstrukt irgendwie zu ändern?
Eine Prozedur FillAdresse, die die Felder füllt und dann die Funktion, die die gewünschten Felder "concatiert" (gibt's das?) ausgibt?
Man könnte z.B. die Funktion GetDebitorName in TAdresse verlagern. Es gibt -zig Möglichkeiten das Problem zu umgehen - deswegen ist es bisher wohl auch nicht aufgefallen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#33

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 17:20
Das Ungewöhnliche ist wohl das hier:
Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Adresse.Vorname := 'a';
  Adresse.Name := 'b';
  Result := Adresse;
end;
Die Zuweisung von 'a' und 'b' im 'Getter' der ReAdr.

Man würde die Eigenschaften der Adresse einmalig setzen z.B. per LazyLoad.
Oder man würde gleich eine protected Property aus der Adresse machen.
  Mit Zitat antworten Zitat
Benutzerbild von bernau
bernau

Registriert seit: 1. Dez 2004
Ort: Köln
1.268 Beiträge
 
Delphi 11 Alexandria
 
#34

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 17:32
Das ist ein "Fehler" im CodeHiglighting, dann das kann dieses nicht richtig auflösen, nur anhand eines Codeabschnittes.

"Name" ist nur reserviert, innerhalb einer Property-Deklaration und bei Prozedurimporten (wo es wiederum der SyntaxHighlighter in der IDE nicht hinbekommt)

Auch wenn es in dem Fall OK ist, wenn "Name" als Property verwendet wird. Ich würde diese Bezeichnung nicht verwenden. Habe früher schon oft nach Fehlern gesucht, weil "Name" dann doch häufiger in Klassen verwendet wird.

Ich verwende für So etwas immer "Vorname" und "Nachname". Das ist dann eindeutiger.

Aber natürlich Geschmackssache.
Gerd
Kölner Delphi Usergroup: http://wiki.delphitreff.de
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hannover-Hainholz
801 Beiträge
 
Delphi 11 Alexandria
 
#35

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 18:24
Das Ungewöhnliche ist wohl das hier:
Delphi-Quellcode:
function TForm1.GetReAdr: TAdresse;
begin
  Adresse.Vorname := 'a';
  Adresse.Name := 'b';
  Result := Adresse;
end;
Die Zuweisung von 'a' und 'b' im 'Getter' der ReAdr.

Man würde die Eigenschaften der Adresse einmalig setzen z.B. per LazyLoad.
Oder man würde gleich eine protected Property aus der Adresse machen.
LazyLoad wird im realen Code verwendet. Fehler tritt trotzdem auf. Auch mit einer protected Property. Das hier ist nun ein komprimierter Code um den Fehler zu zeigen...
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#36

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 19:37
Lazy Load sorgt dafür, das solche Zuweisungen nur einmal durchgeführt werden.
Delphi-Quellcode:
// Also so gehts:
Function TForm1.GetReAdr: TAdresse;
Begin
  If fAddress = Nil Then Begin
    Adresse.Vorname := 'a';
    Adresse.Name := 'b';
    fAddress := Adresse;
  End;
  Result := fAddress;
End;

// Und so auch
Function TForm1.GetReAdr: TAdresse;
Begin
  If not fInitialized Then Begin
    Adresse.Vorname := 'a';
    Adresse.Name := 'b';
    fInitialized := True;
  End;
  Result := Adresse;
End;
Allgemein ist das LazyLoad-Pattern für Properties so:
Delphi-Quellcode:
Function TMyClass.GetProperty : TSomeValue;
Begin
  if fProperty=nil then
    fProperty := CreateSomeValue;
  result := fProperty;
End;
Damit wird nur beim Zugriff, und dann nur beim ersten, instantiiert. Früher nannte man das 'Fetch on demand'. Heute eben 'lazy load'. Und damit schlägt man dem blöden Compiler ein Schnippchen.
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hannover-Hainholz
801 Beiträge
 
Delphi 11 Alexandria
 
#37

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 20:02
Wie gesagt LazyLoad wird verwendet (siehe Post #6) und ändert am Problem nichts...
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#38

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 20:31
Das Problem ist die Referenz-Zählung für die Strings. Bei jeder Zuweisung wird der String an eine andere Speicheradresse geschrieben und die alte Speicheradresse wird als frei markiert.

Es taucht nicht auf, wenn man für die Eigenschaften Name und Vorname einen Getter benutzt
Delphi-Quellcode:
type
  TAdresse = class
  private
    FVorname: string;
    FName: string;
    function GetName: string;
    function GetVorname: string;
  public
    property Vorname: string read GetVorname write FVorname;
    property Name: string read GetName write FName;
  end;
Weiterhin taucht es nicht auf, wenn man die Adresse so zusammensetzt
Delphi-Quellcode:
function TFoo.GetFullName : string;
begin
  Result := GetAdresse.Vorname + GetAdresse.Nachname;
end;
Und wenn man sich mal spasseshalber die Pointer auf die Variablen holt
Delphi-Quellcode:
function TTest.GetFullName : string;
var
  LVorname, LName : PChar;
begin
  LVorname := PChar( GetAdresse.Vorname );
  // jetzt zeigt der Debugger den korrekten Vornamen bei LVorname an
  LName := PChar( GetAdresse.Name );
  // ab jetzt steht in LVorname und LName der gleiche Wert, weil nun die Pointer an die gleiche Stelle zeigen
  Result := GetAdresse.Vorname + GetAdresse.Nachname;
end;
Dieses ist aber eher Zufall, da die beiden Speicherstellen abwechselnd belegt werden, was wir mit folgendem Code überprüfen können
Delphi-Quellcode:
function TTest.GetFullName: string;
var
  LName1, LVorname, LName2 : PChar;
begin
{1}  LName1 := PChar( GetAdresse.Name );
{2}  LVorname := PChar( GetAdresse.Vorname );
{3}  LName2 := PChar( GetAdresse.Name );
end;
Hier die Inhalte jeweils nach der Codezeile
NrLName1LVornameLName2
{1}Lustig--
{2}LustigPeter-
{3}PeterLustigLustig
oder wenn man sich die Pointer-Adressen anschaut, dann (Beispielswerte, die ändern sich eh je nach Start)
NrLName1LVornameLName2
{1}$420C--
{2}$420C$422C-
{3}$420C$422C$422C
Oder hier einmal schön den Wechselreigen mit den Adressen bei der Zuweisung
Codezeile+ Adresse- Adresse
Adresse.Vorname := 'Peter';A 
Adresse.Name := 'Lustig';B 
Zugriff auf Vorname => A  
Adresse.Vorname := 'Peter';CA
Adresse.Name := 'Lustig';AB
Zugriff auf Name => A  
Adresse.Vorname := 'Peter';BC
Adresse.Name := 'Lustig';CA
Der Vollständigkeit halber sei noch erwähnt, dass dieses hier
Delphi-Quellcode:
function TTest.GetFullNameReverse: string;
begin
  Result := GetAdresse.Name + ' ' + GetAdresse.Vorname;
end;
natürlich einwandfrei funktioniert. Warum?
Codezeile+ Adresse- Adresse
Adresse.Vorname := 'Peter';A 
Adresse.Name := 'Lustig';B 
Zugriff auf Name => B  
Adresse.Vorname := 'Peter';CA
Adresse.Name := 'Lustig';AB
Zugriff auf Vorname => C  
Adresse.Vorname := 'Peter';BC
Adresse.Name := 'Lustig';CA
(funktioniert aber auch nur, weil der Speicherbereich noch nicht überschrieben wurde)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (29. Okt 2014 um 20:45 Uhr)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#39

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 20:37
Wie gesagt LazyLoad wird verwendet (siehe Post #6) und ändert am Problem nichts...
Bei mir schon (habs gerade probiert). Es ist ja nichts anderes, als mein 2.Vorschlag. Und ich habe deinen Code aus Post #6 kopiert. Geht. Vielleicht ist dein 'IsInitialized' nicht korrekt.

@Sir Rufo: Nee, oder? Verrückt! Tolle Analyse!

Gut, das ich bei C# bin.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#40

AW: Properties haben nach Zuweisung falsche Werte

  Alt 29. Okt 2014, 21:01
Unter Win64 ist der Pointer-Reigen auch zu beobachten, allerdings sind die Ergebnisse immer korrekt.

Somit wird unter Win64 wohl der Speicherbereich sofort kopiert und bei Win32 wird sich der Pointer gemerkt und zum Schluss zusammenkopiert (mit dem bekannten Ergebnis).

Nur so eine Vermutung und ich will da jetzt auch nicht zu sehr in die Tiefe gehen
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 5   « Erste     234 5      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:07 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz