Autor Beitrag
mactoolz
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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 user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Mi 12.12.2012 um 15:02
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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
ausblenden Delphi-Quelltext
1:
g_AdsOcxCom := TTAdsOcxCom.Create(self , g_BelastRack.m_AxisRef , g_IniFile.TwinCatAdsOcx);					


// KONSTRUKTOR Objekt B
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
constructor TTAdsOcxCom.Create(AOwner: TComponent; var ClassAxis : TTAxisRef ; IniSectionTwinCatAdsOcx : TTAIniSectionTwinCatAdsOcx);
begin
   inherited create(TRUE);   // Thread Objekt pausieren

// Neues Objekt C, hier wird von Objekt A Teile von Strukturen an eine weitere Instanz übergeben
   AsXAX_Kette := TTASKette.Create(ClassAxis.pdtXax1); // 1. Instanz
   AsZAX_Kette := TTASKette.Create(ClassAxis.pdtZax1); // 2. Instanz

-----------------------------------------------------------------------------------

// KONSTRUKTOR Objekt C
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mi 12.12.12 16:28 
Hi,

hier der benötigte Typ. Ist eine Struktur(ByteAlignment)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
   // GESAMTSTRUKTUR EINER ACHSE
   Axis = packed record                         // Struktur EINER Achse
      pntAxInSollPos : _pntAxInSollPos;         // Methodenzeiger
      sAxName        :  string;                 // Achsname
      COM            : AxisCom;                 // KONTROLL-STRUTKUR
      STATE          : AxisState                // STATUS-STRUKTUR
   end;


Danke

MacToolz
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Do 13.12.12 09:19 
Ausprobieren hilft.
ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
    FRec: TTestRec;
  public
    { Public-Deklarationen }
  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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 13.12.12 09:38 
user profile iconmactoolz hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 653
Erhaltene Danke: 160



BeitragVerfasst: Do 13.12.12 10:28 
So groß war der Unterschied IMHO auch nicht, aber bitteschön:
ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
    FRec: TTestRec;
  public
    { Public-Deklarationen }
  end;

...

{ TClassA }

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;

{ TClassB }

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?