class - create

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Mathias
Beiträge: 6912
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class - create

Beitrag von Mathias »

Wieso kommt diese Warnung:
...\standrohrunit.pas(23,17) Warning: An inherited method is hidden by "constructor TStandRohrSchnitt.Create;"
Create ist pubilic, wieso schreibt er was von hidden.

Code: Alles auswählen

  TStandRohrSchnitt = class(TUrAnzeiger)
  public
    constructor Create;
    procedure WriteVertex;
  end;
 
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: class - create

Beitrag von Christian »

weil es in der Vaterklasse schon nen Constructor gibt der genauso auschaut, und du den eigentlich überschreiben solltest denn der könnte ja vllt was sinnvolles tun sonst wär er nicht da. Da der Compiler sich aber nicht sicher sein kann das alles was da ist auch sinn macht, erzeugt er nur ne warnung.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Mathias
Beiträge: 6912
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class - create

Beitrag von Mathias »

Ich hätte den Constructor auch posten sollen, da wird der Vater-Constructor aufgerufen.

Code: Alles auswählen

constructor TStandRohrSchnitt.Create;
begin
  inherited Create;
  Color := vec4(1.0, 0.0, 0.0, 0.0);
end;  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10871
Registriert: Mo 11. Sep 2006, 19:01

Re: class - create

Beitrag von theo »

Ein "override" bei der Deklaration wäre sinnvoll.

Mathias
Beiträge: 6912
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class - create

Beitrag von Mathias »

Wieso override ?

Es ist ja ein ganz gewöhnlicher Nachkomme. Überladen tue ich auch nichts.

Hier schreiben sie, das es bei Destroy zwingen ein overlaod bracht, bei Create nur wen man es überladet.
Link
Zuletzt geändert von Mathias am Do 6. Mär 2014, 23:19, insgesamt 2-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: class - create

Beitrag von m.fuchs »

Du bringst hier gerade Überschreiben (override) und Überladen (overload) durcheinander.
Der Konstruktor von TUrAnzeiger ist wohl mit virtual gekennzeichnet. Deswegen wäre ein override beim Konstruktor der abgeleiteten Klasse ganz nett.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 6912
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class - create

Beitrag von Mathias »

Wen ich dich richtig verstehe, braucht der Nachkomme einer virtual deklarierten Methode ein override.

So wie es in diesem Beispiel ist. Link
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: class - create

Beitrag von m.fuchs »

Mathias hat geschrieben:Wen ich dich richtig verstehe, braucht der Nachkomme einer virtual deklarierten Methode ein override.
Nein, braucht er nicht unbedingt, wie du gesehen hast geht es auch ohne. Die Frage ist nur ob der Nachkomme sich dann so verhält wie du möchtest.
Ein Beispiel zur Verdeutlichung:

Code: Alles auswählen

program PolymorphieTest;
{$mode objfpc}{$H+}
 
uses
  Classes, SysUtils;
 
type
  TBaseClass = class(TObject)
    procedure Test; virtual;
  end;
 
  TOverrideClass = class(TBaseClass)
    procedure Test; override;
  end;
 
  TNonOverrideClass = class(TBaseClass)
    procedure Test;
  end;
 
procedure TNonOverrideClass.Test;
begin
  WriteLn('TNonOverrideClass.Test');
end;
 
procedure TOverrideClass.Test;
begin
  WriteLn('TOverrideClass.Test');
end;
 
procedure TBaseClass.Test;
begin
  WriteLn('TBaseClass.Test');
end;
 
var
  MyObject: TBaseClass;
 
begin
  MyObject := TBaseClass.Create;
  MyObject.Test;
  FreeAndNil(MyObject);
  MyObject := TOverrideClass.Create;
  MyObject.Test;
  FreeAndNil(MyObject);
  MyObject := TNonOverrideClass.Create;
  MyObject.Test;
  FreeAndNil(MyObject);
  ReadLn;
end.
Probier es mal aus. :)
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 6912
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class - create

Beitrag von Mathias »

Interessantes Beispiel.

So sieht man das override macht viel Sinn, ohne diese Deklaration nützt virtual auch nichts.

Das dies geht hätte ich nicht gedacht: MyObject := TOverrideClass.Create; Ich meint das Create müsste immer mit der in var deklarieten Classe übereinstimmen: MyObject := TBaseClass.Create;

Der Befehl ist mir auch neu: FreeAndNil(MyObject); Ich hatte jetzt immer MyObject.Free geschrieben.

Ich hatte unterdessen auch ein Beispiel geschrieben und probiert.
Je nach Ausgabe mit override deklariere oder nicht verhält sich mein Programm anders.

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Forms, StdCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
  { TVater }
 
  TVater = class(TObject)
    constructor Create; virtual;
    procedure Ausgabe; virtual;
  end;
 
  { TKind }
 
  TKind = class(TVater)
    constructor Create; override;
    procedure Ausgabe; override;
  end;
 
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Kind: TKind;
begin
  Kind := TKind.Create;
  Kind.Free;
  Writeln('------------');
end;
 
{ TKind }
 
constructor TKind.Create;
begin
  inherited;
  Writeln('TKind Create');
end;
 
procedure TKind.Ausgabe;
begin
  Writeln('TKind Ausgabe');
  inherited;
end;
 
{ TVater }
 
constructor TVater.Create;
begin
  Writeln('TVater Create');
  Ausgabe;
end;
 
procedure TVater.Ausgabe;
begin
  Writeln('TVater Ausgabe');
end;
 
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: class - create

Beitrag von m.fuchs »

Mathias hat geschrieben:macht viel Sinn
Aua :wink:.
Mathias hat geschrieben:Das dies geht hätte ich nicht gedacht: MyObject := TOverrideClass.Create; Ich meint das Create müsste immer mit der in var deklarieten Classe übereinstimmen: MyObject := TBaseClass.Create;
Nö, es kann auch ein Abkömmling sein. Allerdings kannst du nur auf die Methoden der Basisklasse zugreifen. Und indirekt eben über die virtuellen Methoden auf die eigentliche Klasse.
Mathias hat geschrieben:Der Befehl ist mir auch neu: FreeAndNil(MyObject); Ich hatte jetzt immer MyObject.Free geschrieben.
Ich habe mir fast vollständig abgewöhnt .Free einzusetzen. Somit ist dann auch immer sichergestellt, dass die Referenzvariable danach auf nil zeigt. Bei der Nutzung von Assigned ist das immer hilfreich.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 6912
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class - create

Beitrag von Mathias »

m.fuchs hat geschrieben:
Mathias hat geschrieben:Wen ich dich richtig verstehe, braucht der Nachkomme einer virtual deklarierten Methode ein override.
Nein, braucht er nicht unbedingt, wie du gesehen hast geht es auch ohne. Die Frage ist nur ob der Nachkomme sich dann so verhält wie du möchtest.
Ein Beispiel zur Verdeutlichung:
Jetzt weis ich wieso ich nirgends ein override geschrieben habe, früher habe ich nur mit Objecten gearbeitet, und dort braucht es ein virtual bei den Nachkommen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6912
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class - create

Beitrag von Mathias »

Ist dies der normale Weg, wen man mehrfach-vererbt, bezieht sich auf das override.

Code: Alles auswählen

  { TGrossVater }
 
  TGrossVater = class(TObject)
    constructor Create; virtual;
    procedure Ausgabe; virtual;
  end;
 
  { TVater }
 
  TVater = class(TGrossVater)
    constructor Create; override;
    procedure Ausgabe; override;
  end;
 
  { TKind }
 
  TKind = class(TVater)
    constructor Create; override;
    procedure Ausgabe; override;
  end;         
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: class - create

Beitrag von m.fuchs »

Jepp, genauso ist es richtig.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 6912
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class - create

Beitrag von Mathias »

Wen ich hier gucke, sieht es aus, wie wen ich bei create virtual und override ganz weglassen kann.
Das ich überhaupt auf die Idee ist kam, liegt wahrscheinlich, weil ich overload und override verwechselt hatte.
Das override braucht es nur bei Destroy.

Dazu habe ich noch eine Frage:
Man gibt eine Class mit MyClass.Free frei, wo wird dies freigegeben ?
Der Methode Free und Destroy mach ja nichts.

Ein Ausschnitt aus der Original-Quelle von FreePascal (objpas.inc).

Code: Alles auswählen

      destructor TObject.Destroy;
        begin
        end;
 
      procedure TObject.Free;
 
        begin
           // the call via self avoids a warning
           if self<>nil then
             self.destroy;
        end;                   
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: class - create

Beitrag von m.fuchs »

Mathias hat geschrieben:Wen ich hier gucke, sieht es aus, wie wen ich bei create virtual und override ganz weglassen kann.
Nun, das kommt ganz darauf an, was du brauchst. Mein Beispiel von oben funktioniert nur mit virtual und override. Aber es ist ja nicht gesagt, dass diese Funktionalität gewünscht ist.
Mathias hat geschrieben:Das override braucht es nur bei Destroy.
Da aber dann definitiv.
Mathias hat geschrieben:Dazu habe ich noch eine Frage:
Man gibt eine Class mit MyClass.Free frei, wo wird dies freigegeben ?
Der Methode Free und Destroy mach ja nichts.
Das ist Magie. Die Methode FreeInstance ist für das Aufräumen verantwortlich.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Antworten