2016-11-08 17 views
15

Próbuję odziedziczać z Tdictionary i jakoś domyślny porównań jest utracone. To jest to, co robię w istocie:Delphi Tdictionary dziedziczenie

type 
    TinpVar = class 
    end; 
    TinputVars = class(Tdictionary<string,TinpVar>) 
    end; 
    TLVRvars = class(TinputVars) 
    constructor create; 
    end; 

constructor TLVRvars.create; 
begin 
    inherited; 
end; 

var LVRvars : TLVRvars; 

begin 
    LVRvars:=TLVRvars.create; 

Dzięki tej konstrukcji dostaję AV podczas dodawania parę klucz/wartość do LVRvars. W końcu okazało się, że można temu zapobiec poprzez zmianę konstruktora dziedziczonej klasy

constructor TLVRvars.create; 
begin 
    inherited create; 
end; 

Nie rozumiem, dlaczego mam to zrobić. Chociaż mój problem został rozwiązany, nadal chciałbym wiedzieć.

+0

Czy w ogóle dysponowałeś konstruktorem? – Dsm

Odpowiedz

20

W konstruktora

inherited; 

wywołuje konstruktor z identycznym listy parametr do konstruktora. Twój konstruktor nie ma parametrów, więc inherited wywołuje konstruktor nic nie rób w TObject. Nie tylko straciłeś swojego porównywalnika, ale w instancji brakuje pozostałych niezbędnych kroków konstrukcyjnych.

Kiedy zastąpić go

inherited Create; 

kompilator zamiast wykonuje normalną rozdzielczość metody. Wyszukuje listę przodków klasy i wywołuje pierwszą możliwą metodę. W takim przypadku jest to:

constructor Create(ACapacity: Integer = 0); overload; 

Dlatego Twoja instancja jest prawidłowo utworzona.

Dokumentacja jest tutaj: http://docwiki.embarcadero.com/RADStudio/en/Methods#Inherited

Kluczowe fragmenty są:

Jeśli dziedziczona jest po imieniu członka, reprezentuje normalny wywołanie metody

i

Po odziedziczeniu nie ma po nim żadnego identyfikatora, to s do odziedziczonej metody o tej samej nazwie, co metoda otaczająca lub, jeśli obejmujący sposób jest programem obsługującym komunikaty, do odziedziczonej procedury obsługi wiadomości dla tej samej wiadomości o numerze . W tym przypadku dziedziczenie nie bierze jawnych parametrów, , ale przekazuje do metody dziedziczonej te same parametry, z którymi wywołano metodę obejmującą . Na przykład:

inherited; 

występuje często w realizacji konstruktorów. Wywołuje on odziedziczony konstruktor z tymi samymi parametrami, które zostały przekazane potomkowi .

To dość dziwne, prawda. Na pierwszy rzut oka zdumiewające, że wywoływane są różne metody. Kluczową kwestią jest jednak to, że zwykły inherited prowadzi do dokładnego dopasowania list parametrów. A twoja metoda nie ma parametrów.

Z drugiej strony inherited Create to standardowe wywołanie metody. W tym ostatnim przypadku wywołujesz metodę z jednym parametrem, używając wartości domyślnej dla tego parametru. Tak więc, chociaż wygląda na to, że wywołujesz konstruktora bez parametrów, nie jesteś. Przekazujesz jeden parametr, ACapacity i wartość 0.

+2

Podkreślenie niebezpieczeństw związanych z domyślnymi parametrami. W tym przypadku, co wygląda dokładnie identyczny kod: 'odziedziczony;' (kończy się) wywołanie domyślnego ctor bez parametru ** Utwórz ** kontra 'odziedziczony Utwórz;' który * pojawia się *, aby jawnie wywołać dziedziczony ctor bez parametrów ** Utwórz * * ale w rzeczywistości rozwiązuje do ctor z * domyślnym * parametrem. Dobry połów. – Deltics

-2

Komparator to obiekt, który należy sam utworzyć. Gdybyś nie miał konstruktora w swojej klasie zejścia, oczekiwałbym, że zostanie utworzony domyślny konstruktor, ponieważ będziesz niejawnie wywoływał dziedziczony konstruktor. Jeśli tworzysz własny konstruktor, powinieneś zawsze wywołać dziedziczony Create (według mnie), aby umożliwić przodkowi wykonanie jego pracy - w tym przypadku utworzenie domyślnego komparatora.

+2

Jest to nieco szerszy znak, obawiam się, –