Implementace vlastního správce řetězců (rozšířený způsob)
Ve specializovaných situacích můžete chtít implementovat vlastního správce řetězců, který dělá více než jen změnu haldy, která se používá k přidělení paměti. V této situaci musíte ručně implementovat IAtlStringMgr rozhraní jako vlastní správce řetězců.
Aby to bylo možné provést, je důležité nejprve pochopit, jak CStringT používá toto rozhraní ke správě řetězcových dat. Každá instance CStringT
má ukazatel na strukturu CStringData . Tato struktura s proměnnou délkou obsahuje důležité informace o řetězci (například délce) a také skutečná data znaků pro řetězec. Každý vlastní správce řetězců zodpovídá za přidělování a uvolnění těchto struktur na žádost CStringT
.
Struktura CStringData
se skládá ze čtyř polí:
pStringMgr Toto pole odkazuje na
IAtlStringMgr
rozhraní použité ke správě těchto řetězcových dat. PokudCStringT
je třeba relokovat nebo uvolnit řetězec vyrovnávací paměti, volá Reallocate nebo Free metody tohoto rozhraní, předáníCStringData
struktury jako parametru. Při přidělováníCStringData
struktury ve správci řetězců musíte toto pole nastavit tak, aby odkazoval na vlastního správce řetězců.nDataLength Toto pole obsahuje aktuální logickou délku řetězce uloženého ve vyrovnávací paměti s výjimkou ukončující hodnoty null.
CStringT
aktualizuje toto pole, když se změní délka řetězce. Při přidělováníCStringData
struktury musí správce řetězců nastavit toto pole na nulu. Při skutečnémCStringData
přidělení struktury musí vlastní správce řetězců ponechat toto pole beze změny.nAllocLength Toto pole obsahuje maximální počet znaků (s výjimkou ukončující hodnoty null), které lze uložit v této vyrovnávací paměti řetězce bez jeho skutečného přidělení. Pokaždé, když
CStringT
je potřeba zvětšit logickou délku řetězce, nejprve zkontroluje toto pole, aby se zajistilo, že je v vyrovnávací paměti dostatek místa. Pokud se kontrola nezdaří,CStringT
volání do vašeho vlastního správce řetězců k opětovnému přidělení vyrovnávací paměti. Při přidělování nebo opětovnémCStringData
přidělení struktury musíte toto pole nastavit alespoň na počet znaků požadovaných v parametru nChars na IAtlStringMgr::Allocate nebo IAtlStringMgr::Reallocate. Pokud je ve vyrovnávací paměti více místa, než je požadováno, můžete tuto hodnotu nastavit tak, aby odrážela skutečnou velikost dostupného místa. To umožňujeCStringT
zvětšit řetězec tak, aby vyplnil celý přidělený prostor předtím, než bude muset zavolat zpět do správce řetězců k opětovnému přidělení vyrovnávací paměti.nRefs Toto pole obsahuje aktuální počet odkazů vyrovnávací paměti řetězce. Pokud je hodnota jedna, pak jedna instance
CStringT
používá vyrovnávací paměť. Kromě toho může instance číst i upravovat obsah vyrovnávací paměti. Pokud je hodnota větší než jedna, může vyrovnávací paměť použít více instancíCStringT
. Protože je vyrovnávací paměť znaků sdílena,CStringT
instance mohou číst pouze obsah vyrovnávací paměti. Chcete-li upravit obsah,CStringT
nejprve vytvoří kopii vyrovnávací paměti. Pokud je hodnota záporná, používá vyrovnávací paměť pouze jedna instanceCStringT
. V tomto případě se vyrovnávací paměť považuje za uzamčenou.CStringT
Pokud instance používá uzamčenou vyrovnávací paměť, žádné jiné instanceCStringT
nesmí sdílet vyrovnávací paměť. Místo toho tyto instance vytvoří kopii vyrovnávací paměti před manipulací s obsahem. Kromě toho seCStringT
instance používající uzamčenou vyrovnávací paměť nepokoušá sdílet vyrovnávací paměť žádné jinéCStringT
instance, která je k ní přiřazena. V tomto případěCStringT
instance zkopíruje druhý řetězec do uzamčené vyrovnávací paměti.Při přidělování
CStringData
struktury je nutné nastavit toto pole tak, aby odráželo typ sdílení, který je pro vyrovnávací paměť povolený. U většiny implementací nastavte tuto hodnotu na jednu. To umožňuje obvyklé chování sdílení kopírování při zápisu. Pokud však správce řetězců nepodporuje sdílení vyrovnávací paměti řetězce, nastavte toto pole na uzamčený stav. To vynutíCStringT
, aby tuto vyrovnávací paměť používala pouze pro instanciCStringT
, která ji přidělila.