Szablony i dziedziczenie.

0

Czesc,
robiliscie (albo widzieliscie, zeby ktos tak robil):

mam klase A z szablonem
a nastepnie dziedziczye po tej klasie
ale podajac juz jakas konkretna klase-parametr.
Zatem klasa B juz nie wymaga parametru.

Zrobilem tak i sie skompilowalo...
ale jakies czary wychodza a nie program:/

konkretnie
pole z klasy A ma ten sam adres w pamieci co pole klasy B.
czyli zapisujac cos do jednego, nadpisuje w drugim...

TPrzodekParametru = class
end;

TKonkretnyParametr = class(TPrzodekParametru)
end;

TKlasa_A<T: TPrzodekParametru> = class
	// klasa wymaga podania parametru dziedziczacego po 
	// TPrzodekParametru
end;

TKlasa_B = class(TKlasa_A<TKonkretnyParametr>)
	// podaje odpowiedni paramter
	// dzieki czemu kozystajac z klasy B
	// nie musze juz podawac parametru
end;
 

i konkretne zastosowanie:

var obiektB: TKlasa_B;
begin
	obiektB := TKlasa_B.create;
end;
 

Czy takie pokrecone konstrukcje maja szanse dzialac?
kompilator lykna bez problemu... wiec wydaje sie ze powinno byc ok...

0

ale jakie pole? Nigdzie tu nie masz żadnych pól i tak nie do końca wiadomo o co Ci chodzi

0

hehe nie dalem pol bo chodzilo mi konkretnie o to czy taka konstrukcja laczaca dziedziczenie z szablonami jest poprawna.
Ale jestem coraz bardziej przekonany ze jest OK.

ale juz uzupelniam:

TPrzodekParametru = class
end;
 
TKonkretnyParametr = class(TPrzodekParametru)
end;
 
TKlasa_A<T: TPrzodekParametru> = class
        // klasa wymaga podania parametru dziedziczacego po 
        // TPrzodekParametru
protected
  ListaElementow: TObjectList<T>;
  procedure nieistotnaProcedura1;
  procedure nieistotnaProcedura2;
public
  nieistotnepole1: integer;
  nieistotnepole2: TObject;
  constructor Create();
end;
 
TKlasa_B = class(TKlasa_A<TKonkretnyParametr>)
        // podaje odpowiedni paramter
        // dzieki czemu kozystajac z klasy B
        // nie musze juz podawac parametru
protected
  vCanvas: TCanvas;
  function nieistotnafunkcja1: integer;
public
  nieistotnepole3: TObject;
  nieistotnepole4: TObject;
  constructor Create(aCanvas: TCanvas);
end;
 

no a w konstruktorach:

 
constructor TClasa_A<T>.create();
begin
  ListaElementow := TList<T>.create;
end;

constructor TClasa_B.create(aCanvas: TCanvas);
begin
{1}  inherited Create;
{2}  vCanvas := aCanvas;
end;

Gdy stawiam breakpoint na linijce '1' i sprawdzam adresy pol to otrzymuje takie (przykladowe) wartosci:
@ListaElementow = $4B09610
@vCanvas = $4B09610

// te same wartosci

po wykonaniu linijki '1' ListaElementow jest poprawnie zainicjowana,
niestety po wykonaniu linijki '2' zawiera juz smieci... (bo parametr klasy TCanvas zostal wstawiony w to samo miejsce)

Nie moge zrozumiec dlaczego tak sie dzieje....
Jesli jest jakies logiczne wytlumaczenie, prosze bardzo o komentarz.

pozdrawiam

0

w (1) vCanvas i ListaElementow powinny mieć wartość nil
w (2) ListaElementow powinna mieć już jakiś adres a vCanvas dalej nil
po (2) vCanvas powinien mieć adres aCanvas (żeby to sprawdzić to pewnie będziesz musiał dodać jakieś polecenie przed end)
daj pomiędzy (1) i (2) np. ListaElementow.Add(nil) a potem ListaElementow.Clear i zobacz czy się wykona. Dodaj to samo po (2) i też zobacz co się stanie.
Nie mam teraz DXE pod ręką więc nie powiem Ci na 100% ale jak dla mnie konstrukcja wygląda poprawnie i powinna działać. Inna sprawa jakie to Delphi jest bo pierwsze generyki mocno kulały i dopiero w kolejnej wersji delphi działały już znacznie lepiej

1 użytkowników online, w tym zalogowanych: 0, gości: 1