Autor |
Beitrag |
mactoolz
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 12.12.12 15:39
Hallo zusammen,
ich habe ein Globales Objekt KlasseA.
Dieses globale Objekt wird an eine KlasseB CreateMethode als CallBYReference übergeben.
Diese Createmethode hat weitere Instanzen die erstellt werden sollen KlasseC.
In KlasseB wird der Konstruktur von KlasseC aufgerufen, der aus der KlasseB als Übergabeparameter CBR (KlasseA) sich Elemente heraus nimmt
und diese als CBR an die weitere CreateMethode übergibt.
Bedeutet das, wenn ich auf das globale KlasseA Elemente verändere, das diese sich dann auch in der KlasseC das Element verändert.
Kann mir da jemand folgen.
MacToolz Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Mi 12.12.2012 um 15:02
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 12.12.12 15:52
Bei Klassen ist es egal, wie du den Parameter übergibst, da das intern alles Pointer auf Objekte sind. Wenn du also das Objekt einmal erstellst und in andere Variablen oder als Parameter weitergibst, ist das auch alles noch das selbe Objekt.
Statt abstrakt zu beschreiben was du tust, wäre ein kurzer Beispielquelltext einfacher gewesen. 
|
|
mactoolz 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 12.12.12 16:08
Hi,
dann mal ein Stück Code
Objekt A: Instanz
g_BelastRack := TTABelastRack.Create(self, SectionCount, MaxPlacesOfSections());
-----------------------------------------------------------------------------------
Objekt B: bekommt von Objekt A etwas
Delphi-Quelltext 1:
| g_AdsOcxCom := TTAdsOcxCom.Create(self , g_BelastRack.m_AxisRef , g_IniFile.TwinCatAdsOcx); |
// KONSTRUKTOR Objekt B
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| constructor TTAdsOcxCom.Create(AOwner: TComponent; var ClassAxis : TTAxisRef ; IniSectionTwinCatAdsOcx : TTAIniSectionTwinCatAdsOcx); begin inherited create(TRUE); AsXAX_Kette := TTASKette.Create(ClassAxis.pdtXax1); AsZAX_Kette := TTASKette.Create(ClassAxis.pdtZax1); |
-----------------------------------------------------------------------------------
// KONSTRUKTOR Objekt C
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| constructor TTASKette.Create(var SpsAxis : Axis); begin m_eAsStep := as_INIT; m_Axis := SpsAxis; m_AxName := SpsAxis.sAxName; end; |
-----------------------------------------------------------------------------------
Kann man das so hier anzeigen?
Reicht das erstmal so in der Art
Zuletzt bearbeitet von mactoolz am Mi 12.12.12 16:28, insgesamt 2-mal bearbeitet
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 12.12.12 16:23
Du kannst Quelltext mit <span class="inlineSyntax"><span class="codecomment">{PROTECTTAGad5553b2d50efdf65702be05cd4be7e8}</span></span> auch formatiert posten.
Wie ist denn der Typ Axis aus var SpsAxis : Axis deklariert? Ist das eine Klasse? Dann ist das auch das selbe Objekt nach der Weitergabe (egal ob mit var-Parameter oder nicht).
|
|
mactoolz 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 12.12.12 16:28
Hi,
hier der benötigte Typ. Ist eine Struktur(ByteAlignment)
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| Axis = packed record pntAxInSollPos : _pntAxInSollPos; sAxName : string; COM : AxisCom; STATE : AxisState end; |
Danke
MacToolz
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 12.12.12 16:48
Dann wird die bei der Zuweisung kopiert, eine Änderung an der ursprünglichen Struktur wirkt sich dann nicht aus.
Ändern könntest du das indem du nur einen Pointer darauf weitergibst, aber sinnvoller wären dafür Klassen und Objekte.
Nebenbei:
Typen in Delphi beginnen per Konvention immer mit einem T, Ausnahme sind Interfaces mit einem I. Statt Axis wäre daher TAxis besser als Name. Aber das wirklich nur nebenbei.
|
|
mactoolz 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 12.12.12 16:55
Hi,
ok die Namenskonventionen werde ich mir zu herzen nehmen.
Wenn aber eine Objektklasse als Übergabeparameter wie ein Zeiger behandelt wird,
warum komme ich denn nicht an die Inhalte der Klasse, innerhalb der weiter gereichten Klassen?
Die Referenz, die eigentliche Klasse "g_BelastRack" die weitergegeben wird,
ist ja schon ein Zeiger auf dieses Objekt.
Wenn dann doch aus diesee Referenz einzelne Elemente mit VAR
weiter an weitere Klassen übergeben werden, sollten diese doch
die selben sein und somit auch ihren geänderten Inhalt über das globale Objekt
mitbekommen. So meine denke. Aber dem scheint nicht so und das verstehe ich gerade nicht.
Vielleicht nochmal eine Unterstützung
Danke
MacToolz
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Mi 12.12.12 16:59
Ich verstehe nicht ganz, was Du willst. Du übergibst als Parameter einer Methode einer Klasse eine Property einer anderen Klasse, welche dann innerhalb der Methode geändert werden soll?
|
|
mactoolz 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 12.12.12 17:08
Hallo,
was hat das mit dem Property denn zu tun? Ich bin noch bei der Instanzierung aller Objekte.
Der Ablauf von meinem Programm ist folgender. Ich lese erstmal INI Files ein, dann werden die INI Blöcke
durch meine Konstruktoren befüllt und weitere benötigte Objekte instanziert.
Anschließend wenn alle Objekte erstellt worden sind, muss ich eine Methode aufrufen die mir Handle von Strukturen
von einer SPS erzeugen. Diese Handle werden dann in eines der globalen Objekte in den Strukturen beschrieben.
Anschließend wenn das alles erfolgreich abgelaufen ist, öffne ich einen Thread der mit diesen Handle dann arbeiten muss.
So mal im groben.
Verstehe nicht wie du das meinst.?
MacToolz
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Mi 12.12.12 17:20
Zitat: | Wenn dann doch aus diesee Referenz einzelne Elemente mit VAR weiter an weitere Klassen übergeben werden |
Das "einzelne Element der Referenz" klang mir mach Property, aber wir verwenden anscheinend unterschiedliche Begrifflichkeiten. Zumindest ist mir klar, dass ich immer noch weiß, was Du eigentlich möchtest bzw. wo das Problem liegt.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 12.12.12 17:34
Übergeben tust du aber nicht das Objekt, sondern ein Feld daraus (ClassAxis.pdtXax1), eben vom Typ Axis. Und das ist kein Objekt. Deshalb wird in dem Moment kein Pointer gespeichert, sondern eine Kopie des Records.
|
|
mactoolz 
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 13.12.12 09:03
Morgen zusammen,
also gut, dann sehe ich den Unterschied. Ich dachte mit CallByReference wäre die sache damit erschlagen auch wenn es ein Feld aus einem Objekt wäre.
Ok, wie müsste ich denn jetzt vorgehen. Ich habe in meiner Klasse eine Zeigertyp definiert der vom Typ Axis ist.
Ich übergebe erstmal das Objekt und wenn ich an eine weitere Methode das Feld übergebe, dann die adresse von diesem Feld.
Wäre das so richtig?
MacToolz
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Do 13.12.12 09:19
Ausprobieren hilft.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62:
| type TTestRec = record SomeVal: integer; end;
TClassA = class public procedure Method1(var ARec: TTestRec); end;
TClassB = class public procedure Method2(Value: PInteger); end;
TfrmTest = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); private FRec: TTestRec; public end;
...
procedure TfrmTest.Button1Click(Sender: TObject); var ClassA: TClassA; ClassB: TClassB; begin ClassB := nil; ClassA := TClassA.Create; try ClassA.Method1(FRec); ShowMessage(IntToStr(FRec.SomeVal)); ClassB := TClassB.Create; ClassB.Method2(@FRec.SomeVal); ShowMessage(IntToStr(FRec.SomeVal)); finally ClassA.Free; ClassB.Free; end; end;
procedure TfrmTest.FormCreate(Sender: TObject); begin FRec.SomeVal := 10; end;
procedure TClassA.Method1(var ARec: TTestRec); begin ARec.SomeVal := 1; end;
procedure TClassB.Method2(Value: PInteger); begin if Assigned(Value) then Value^ := 42; end; |
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 13.12.12 09:38
mactoolz hat folgendes geschrieben : | Ok, wie müsste ich denn jetzt vorgehen. Ich habe in meiner Klasse eine Zeigertyp definiert der vom Typ Axis ist.
Ich übergebe erstmal das Objekt und wenn ich an eine weitere Methode das Feld übergebe, dann die adresse von diesem Feld. |
Warum so kompliziert? Mach aus TAxis einfach eine Klasse und damit hat sich die ganze Sache...
Die erzeugst du im Konstruktor deiner bisherigen Klasse und gibst sie im Destruktor frei. Damit existiert sie solange das Elternobjekt existiert.
|
|
mactoolz 
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 13.12.12 10:03
Hi,
also meine Fragestellung ist eine ganz andere als du hier als Codebeispiel geliefert hast, danke dafür trotzdem.
Mein Unterschied zu Deimem Code ist, das ich mein Feld in eine weiteres Klassenobjekt weiter durchreiche möchte
und nicht innerhalb der Klasse mit zwei verschiedenen Methoden arbeite und hier dann die Werte verändere.
Das heißt und das funktioniert auch, bin noch nicht ganz mit der Syntax vertraut aber der Debugger hat es mir bestätigt und
mein Programm auch.
Ich übergebe das Klassenobjekt an eine Instanz, da ein Klassenobjekt ja eh als Zeiger intern verarbeitet als Übergabeparameter,
brauche ich hier nichts weiter mit Zeiger dafür zu implementieren.
Das Feld aus dem Klassenobjekt, wird als Adresse an ein weiteres Klassenobjekt übergeben. In diesem Klassenobjekt
habe ich dann mein Member Zeigertyp, der als Typ auf diese Axis Struktur zeigt, das bedeutet beim Konstruktoraufruf nehme ich dann die Adresse
von diese Feld und weise diese Adresse meinen Zeigertyp (Axis) zu.
Fertig, somit habe ich von einem Klassenobjekt in einer anderen Klassenobjekt das Feld übergeben.
Danke
MacToolz
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: Do 13.12.12 10:28
So groß war der Unterschied IMHO auch nicht, aber bitteschön:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86:
| type PTestRec = ^TTestRec;
TTestRec = record SomeVal: integer; end;
TClassB = class;
TClassA = class private FRec: PTestRec; FClassB: TClassB; public constructor Create(Rec: PTestRec); destructor Destroy; override; procedure DoSomething; end;
TClassB = class private FSomeValue: PInteger; public constructor Create(Value: PInteger); procedure DoSomething; end;
TfrmTest = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private FRec: TTestRec; public end;
...
constructor TClassA.Create(Rec: PTestRec); begin FRec := Rec; if Assigned(FRec) then FClassB := TClassB.Create(@FRec.SomeVal); end;
destructor TClassA.Destroy; begin FClassB.Free; inherited; end;
procedure TClassA.DoSomething; begin if Assigned(FClassB) then FClassB.DoSomething; end;
constructor TClassB.Create(Value: PInteger); begin FSomeValue := Value; end;
procedure TClassB.DoSomething; begin if Assigned(FSomeValue) then FSomeValue^ := 42; end;
procedure TfrmTest.Button1Click(Sender: TObject); var ClassA: TClassA; begin FRec.SomeVal := 1000; ClassA := TClassA.Create(@FRec); try ClassA.DoSomething; ShowMessage(IntToStr(FRec.SomeVal)); finally ClassA.Free; end; end; |
Ist es das, was Du wolltest?
|
|