TObject a jeho metody

vložil Radek Červinka 24. května 2010 23:38

Veskrze každý zná základní třídu TObject a její metody jako Free, constructor Create a destructor Destroy. Asi znáte i užitečnou class function ClassName, která vrací název třídy a sem tam šikovné metody ClassType a ClassParent, které vrací TClass, tj. referenci na třídu za běhu.

Rád bych upozornil na některé zajímavé elementy deklarace TObject. Níže je deklarace třídy tak, jak je v Delphi 2010.

Modří již vědí, že v Delphi 2009 došlo k rozšíření o čtyři kousky a to o class function UnitName a tři virtuální metody - Equals, GetHashCode a ToString - velmi užitečné a navíc prudce zvyšující kompatibilitu s Delphi Prism a .NET.

Delphi 2010 jen navíc určuje viditelnost na public (asi vzhledem k novému RTTI) a ClassInfo je inline.

Deklarace TObject

    1TObject = class
    2  public
    3    constructor Create;
    4    procedure Free;
    5    class function InitInstance(Instance: Pointer): TObject;
    6    procedure CleanupInstance;
    7    function ClassType: TClass; inline; 
    8    class function ClassName: string;
    9    class function ClassNameIs(const Name: string): Boolean;
   10    class function ClassParent: TClass;
   11    class function ClassInfo: Pointer; inline;
   12    class function InstanceSize: Longint; inline;
   13    class function InheritsFrom(AClass: TClass): Boolean;
   14    class function MethodAddress(const Name: ShortString): Pointer; overload;
   15    class function MethodAddress(const Name: string): Pointer; overload;
   16    class function MethodName(Address: Pointer): string;
   17    function FieldAddress(const Name: ShortString): Pointer; overload;
   18    function FieldAddress(const Name: string): Pointer; overload;
   19    function GetInterface(const IID: TGUID; out Obj): Boolean;
   20    class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
   21    class function GetInterfaceTable: PInterfaceTable;
   22    class function UnitName: string;
   23    function Equals(Obj: TObject): Boolean; virtual;
   24    function GetHashCode: Integer; virtual;
   25    function ToString: string; virtual;
   26    function SafeCallException(ExceptObject: TObject;
   27      ExceptAddr: Pointer): HResult; virtual;
   28    procedure AfterConstruction; virtual;
   29    procedure BeforeDestruction; virtual;
   30    procedure Dispatch(var Message); virtual;
   31    procedure DefaultHandler(var Message); virtual;
   32    class function NewInstance: TObject; virtual;
   33    procedure FreeInstance; virtual;
   34    destructor Destroy; virtual;
   35  end;

Jak jsem řekl, ClassType je málo využívaná, většinou si člověk vystačí s is a as, ale např. můžete mít za běhu seznam tříd (ne objektů) a v kombinaci s ClassName vybrat požadovanou třídu a její referenci získanou právě přes ClassType předat dále ke zpracování atd.

ClassParent jsem použil např. tak, že jsem měl definován seznam názvů tříd formulářů a k nim definovanou externě ikonu. A při požadavku na vznik některého následníka, jsem našel poslední definovanou ikonu v hierarchii požadované třídy. Ale určitě Vás napadne i jiné použití.

ClassInfo vrací ukazatal na RTTI. Pro pěknou práci s RTTI slouží jednotka typinfo a už tu RTTI bylo. InstanceSize vrací překvapivě velikost instance. writeln(TObject.InstanceSize); vrátí 8 byte.

TObject.AfterConstruction a TObject.BeforeDestruction

AfterConstruction a BeforeDestruction jsou volány v patřičných okamžicích, ve VCL jsou používány např. na vytvoření TForm.OnCreate. Podle helpu BeforeDestruction není volán, pokud došlo v konstruktoru k výjimce.

    1type
    2  TDemoObject = class (TObject)
    3  public
    4    constructor Create;
    5    destructor Destroy; override;
    6    procedure AfterConstruction; override; // po posledním konstruktoru
    7    procedure BeforeDestruction; override;
    8  end;
    9
   10{ TDemoObject }
   11
   12procedure TDemoObject.AfterConstruction;
   13begin
   14  writeln('AfterConstruction');
   15end;
   16
   17procedure TDemoObject.BeforeDestruction;
   18begin
   19  writeln('BeforeDestruction');
   20end;
   21
   22constructor TDemoObject.Create;
   23begin
   24   writeln('Create');
   25end;
   26
   27destructor TDemoObject.Destroy;
   28begin
   29  writeln('Destroy');
   30  inherited;
   31end;
   32
   33begin
   34  with TDemoObject.Create do
   35    Free;
   36end.

Výsledek běhu:

Create
AfterConstruction
BeforeDestruction
Destroy

TObject.UnitName

UnitName by neměl ničím překvapit.

    1program Muj.Cool.Project.SP2;
    2{$APPTYPE CONSOLE}
    3uses
    4  SysUtils;
    5type
    6  TDemoObject = class (TObject);
    7begin
    8  writeln(TDemoObject.UnitName);
    9end.

Vypíše: Muj.Cool.Project.SP2, čímž se nenápadně dostáváme k tomu, že názvy jednotek mohou být strukturované.

TObject.Equals

Nová metoda, která vrací zda jsou instance stejné. V základu toho moc neumí, ale jelikož je virtuální tak se otevírají zajímavé možnosti.

    1function TObject.Equals(Obj: TObject): Boolean;
    2begin
    3  Result := Obj = Self;
    4end;

TObject.ToString

Základní implementace volá ClassName tj. název třídy.

    1function TObject.ToString: string;
    2begin
    3  Result := ClassName;
    4end;

Mezi třídy, které ji předefinovávají patří třeba TStringWriter nebo Exception.

TObject.GetHashCode

Opět nová virtuální metodu, která vrací integer s hashcode. Základní implementace:

    1function TObject.GetHashCode: Integer;
    2begin
    3  Result := Integer(Self);
    4end;

Osobně nechápu proč není nějaká jednoduchá funkce na získání hashe stringu ( - už jsem ji našel, viz dále), takže použijte následující kód.

    1program TestHash;
    2
    3{$APPTYPE CONSOLE}
    4uses
    5  Generics.Defaults;
    6
    7function GetHashCode(const s:AnsiString):Integer;
    8begin
    9  Result := BobJenkinsHash(s[1], Length(s) * SizeOf(s[1]), 0);
   10end;
   11
   12begin
   13  writeln(GetHashCode('delphi.cz'));
   14end.

No a nebo použijte SysUtils.HashName - writeln(HashName('delphi.cz'));


Nabízíme Delphi školení na různá témata, primárně ve Vaší firmě.

Tagy: , , , ,

Praxe

Komentování ukončeno

Naše nabídka

Partial English version.

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy nebo burzy práce).

Pokud chcete podpořit tento server libovolnou částkou, můžete použít PayPal. Moc děkuji.

Delphi Certified Developer

O Delphi.cz

Delphi je jediný moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64 , Mac OSX a na iPhone a Android (s výhledem na další platformy díky FireMonkey) na současném trhu (včetně Windows 8.1).

V současnosti je světová komunita přes dva miliónů vývojářů.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Anketa

Poslední komentáře

Comment RSS