Hlavnφ
Hlavnφ strana
Seznam Φlßnk∙
NejΦten∞jÜφ Φlßnky
Progres e-mailem
Visual C++ FAQ

Serißly
COM
ISAPI

banner1.gif (2545 bytes)

Nenechte si ujφt
NeobdΘlnφkovß okna
Tisk bez Preview
MFC a DLL
Logo v MDI ploÜe
Kouzla s kombo-boxem
V²jimky v C++

banner.gif (3305 bytes)

Srovnßnφ CList a CObList Radek Paviensk²
02.10.1999
[Hlavnφ strßnka]  |  [Rubrika]

Na kurzech se velmi Φasto setkßvßm s dotazem, jak² je rozdφl mezi Üablonovou verzφ seznamu (CList) a t°φdnφ verzφ (CObList). Vzhledem k tomu, ₧e neexistuje jednoznaΦnß odpov∞∩ typu: zßsadn∞ pou₧φvejte CList nechßme prob∞hnout boj mezi ob∞ma t°φdami a to v n∞kolika kolech.

Abychom mohli oba p°φstupy srovnßvat, vytvo°φme si nßsledujφcφ t°φdu (pro jednoduchost uvßdφm pouze deklarace):

class PRO_Ancest : public CObject
{
  // Data
  // -----------------------------------------------
  public:
  int m_nData;
  
  // Konstrukce
  // -----------------------------------------------
  PRO_Ancest();

  // Virtußlnφ operace
  // -----------------------------------------------
  virtual void Print();
  virtual void Serialize(CArchive &ar);
}

Soupe°e mßme, mßme i s Φφm bojovat (₧e by C++?), tedy vzh∙ru do bitvy.

Kolo prvnφ - univerzßlnost

èablona CList nßm umo₧≥uje vytvß°et obousm∞rn∞ vßzanΘ seznamy libovolnΘho typu, p°iΦem₧ tento typ je urΦen a₧ v definici prom∞nnΘ (v∞tÜinou ΦlenskΘ prom∞nnΘ). Naopak t°φda CObList umo₧≥uje vytvß°et pouze seznamy ukazatel∙ na objekty typu  CObject. Vezmeme-li tedy hledisko univerzßlnosti, vφt∞zem je Üablonovß verze seznamu a dostßvßme se na sk≤re 1:0 pro Üablony..

// Definice seznamu ukazatel∙ na CObject a potomky
CObList oListCla;
// Definice seznamu ukazatel∙ na PRO_Ancest a potomky
CList<PRO_Ancest*, PRO_Ancest*> oListTem;
// Vytvo°enφ n∞jak²ch instancφ
PRO_Ancest *poAnc = new PRO_Ancest();

// Vlo₧enφ do prvnφho seznamu
oListCla.AddTail(poAnc);

// Vlo₧enφ do druhΘho seznamu
oListTem.AddTail(poAnc);

Jak je vid∞t, tak mezi Üablonovou a t°φdnφ verzφ nenφ patrn² ₧ßdn² rozdφl a sk≤re tedy z∙stßvß stßle na 1:0.. Ale to je jen zdßnφ, kterΘ hned vyvrßtφme v nßsledujφcφm fragmentu k≤du:

Kolo druhΘ - bezpeΦnost

// Vytvo°φme instanci t°φdy, kterß d∞dφ z CObject
CWnd *poWnd = new CWnd();
oListCla.AddTail(poWnd);  // OK
oListTem.AddTail(poWnd);  // Synt. chyba

A je to tady - vlo₧enφ ukazatele na instanci t°φdy CWnd do seznamu je asi chyba, to je z°ejmΘ, ale t°φdnφ verze to za chybu nepova₧uje, kde₧to pro Üablonovou verzi to chyba je, a to dokonce syntaktickß. Dφky tomu, ₧e Üablonovß verze je konkrΘtn∞jÜφ, podlΘhß k≤d lepÜφ syntaktickΘ kontrole. Z toho plyne, ₧e Üablony zφskßvajφ bod a sk≤re je 2:0.

Podφvejme se na p°φstup k prvk∙m v seznamu (nap°φklad k tomu poslednφmu):

PRO_Ancest *poAncest;
poAncest = (PRO_Ancest*) oListCla.GetTail(); // p°etyp. je nutnΘ
poAncest = oListTem.GetTail();

A vzhledem k tomu, ₧e p°etypovßnφ nenφ v∙bec bezpeΦnß technika (lze p°etypovat cokoli na cokoliv), zφskßvß Üablona dalÜφ bod a posouvß sk≤re na 3:0 ve sv∙j prosp∞ch.

Kolo t°etφ - perzistence

Poslednφ disciplφnou, ve kterΘ nechßme seznamy sout∞₧it, je perzistentnost (uklßdßnφ na disk) - mechanismus serializace. Jak Üablona CList, tak i t°φda CObList majφ virtußlnφ metody Serialize pracujφcφ s archivem. Uklßdßnφ by tedy vypadalo takto:

// instance ar je typu CArchive& a zφskali jsme ji nap°φklad
// v metod∞ Serialize dokumentu
oListCla.Serialize(ar);
oListTem.Serialize(ar);

Zdß se, ₧e sk≤re z∙stane stejnΘ, ale nenφ tomu tak, proto₧e bod p°ekvapiv∞ zφskßvß t°φdnφ verze seznamu - stav tedy je 3:1. Äe by nespravedliv² rozhodΦφ? V∙bec ne! Je to za to, ₧e Üablonovß verze ulo₧φ naprostΘ nesmysly. Musφme si vysv∞tlit jak fungujφ metody Serialize v jednotliv²ch p°φpadech. T°φdnφ verze Serialize d∞lß to, ₧e krom∞ internφch dat zavolß pro vÜechny vlo₧enΘ instance jejich metody Serialize, Φφm₧ jφm dß mo₧nost ulo₧it se. èablonovß verze krom∞ ulo₧enφ internφch dat ud∞lß to, ₧e na disk ulo₧φ ukazatele, kterΘ po vypnutφ a zapnutφ samoz°ejm∞ ztrßcejφ v²znam a pokud k nim p°istoupφme, dojde pravd∞podobn∞ k pßdu aplikace.

Zßv∞r

V²sledek 3:1 asi mluvφ za vÜe. VÜude kde to jen lze, pou₧φvejme ÜablonovΘ verze (platφ i pro CArray a CMap), kterΘ jsou bezpeΦn∞jÜφ a univerzßln∞jÜφ. JedinΘ na co musφme dßvat pozor, je pou₧itφ mechanismu Serialize, kter² u Üablonov²ch verzφ musφme implementovat vlastnφmi silami, co₧ ale nenφ nic slo₧itΘho (t°i °ßdky k≤du).


PodobnΘ Φlßnky: Kolekce v MFC, Jak na CList?,

Kdo Otßzka nebo p°ipomφnka

Prohlφ₧enφ p°φsp∞vk∙ nebo nov² p°φsp∞vek

O firm∞... Kontakt Ostatnφ