Klasy zasad kopii ATL
Klasy zasad kopiowania to klasy narzędzi używane do inicjowania, kopiowania i usuwania danych. Klasy zasad kopiowania umożliwiają definiowanie semantyki kopiowania dla dowolnego typu danych oraz definiowanie konwersji między różnymi typami danych.
Usługa ATL używa klas zasad kopiowania w swoich implementacjach następujących szablonów:
Hermetyzując informacje potrzebne do kopiowania lub konwertowania danych w klasie zasad kopiowania, którą można przekazać jako argument szablonu, deweloperzy ATL zapewnili ekstremalną możliwość ponownego zastosowania tych klas. Jeśli na przykład musisz zaimplementować kolekcję przy użyciu dowolnego typu danych, wystarczy podać odpowiednie zasady kopiowania; nigdy nie trzeba dotykać kodu implementujące kolekcję.
Definicja
Z definicji klasa, która udostępnia następujące funkcje statyczne, jest klasą zasad kopiowania:
static void init(
DestinationType
* p);
static HRESULT copy(
DestinationType
* pTo, const
SourceType
* pFrom);
static void destroy(
DestinationType
* p);
Typy i Typ źródła można zastąpić DestinationType
dowolnymi typami danych dla każdej zasady kopiowania.
Uwaga
Chociaż można zdefiniować klasy zasad kopiowania dla dowolnych typów danych, użycie klas w kodzie ATL powinno ograniczać typy, które mają sens. Na przykład w przypadku używania klasy zasad kopiowania z implementacjami kolekcji lub modułu wyliczającego ATL musi być typem, DestinationType
który może być używany jako parametr w metodzie interfejsu COM.
Użyj init , aby zainicjować dane, skopiować dane i zniszczyć je, aby zwolnić te dane. Dokładne znaczenie inicjowania, kopiowania i zniszczenia to domena klasy zasad kopiowania i będzie się różnić w zależności od zaangażowanych typów danych.
Istnieją dwa wymagania dotyczące użycia i implementacji klasy zasad kopiowania:
Pierwszy parametr do skopiowania musi odbierać wskaźnik tylko do danych, które zostały wcześniej zainicjowane przy użyciu init.
niszczenie musi zawsze otrzymywać wskaźnik do danych, które zostały wcześniej zainicjowane przy użyciu init lub skopiowane za pośrednictwem kopii.
Implementacje standardowe
Usługa ATL udostępnia dwie klasy zasad kopiowania w postaci klas szablonów _Copy
i :_CopyInterface
Klasa
_Copy
umożliwia kopiowanie homogeniczne (nie konwersję między typami danych), ponieważ oferuje tylko jeden parametr szablonu do określenia parametruDestinationType
i SourceType. Ogólna implementacja tego szablonu nie zawiera kodu inicjalizacji ani zniszczenia i służymemcpy
do kopiowania danych. ATL udostępnia również specjalizacje_Copy
typów danych VARIANT, LPOLESTR, OLEVERB i CONNECTDATA.Klasa
_CopyInterface
zapewnia implementację do kopiowania wskaźników interfejsu zgodnie ze standardowymi regułami COM. Po raz kolejny ta klasa umożliwia tylko homogeniczne kopiowanie, więc używa prostego przypisania i wywołania doAddRef
wykonania kopii.
Implementacje niestandardowe
Zazwyczaj należy zdefiniować własne klasy zasad kopiowania na potrzeby kopiowania heterogenicznego (czyli konwersji między typami danych). Aby zapoznać się z przykładami niestandardowych klas zasad kopiowania, zapoznaj się z plikami VCUE_Copy.h i VCUE_CopyString.h w przykładzie ATLCollections . Te pliki zawierają dwie klasy zasad kopiowania szablonów i GenericCopy
, oraz MapCopy
wiele specjalizacji GenericCopy
dla różnych typów danych.
GenericCopy
GenericCopy
Umożliwia określenie wartości SourceType i DestinationType
jako argumentów szablonu. Oto najbardziej ogólna forma GenericCopy
klasy z VCUE_Copy.h:
template <class DestinationType, class SourceType = DestinationType>
class GenericCopy
{
public :
typedef DestinationType destination_type;
typedef SourceType source_type;
static void init(destination_type* p)
{
_Copy<destination_type>::init(p);
}
static void destroy(destination_type* p)
{
_Copy<destination_type>::destroy(p);
}
static HRESULT copy(destination_type* pTo, const source_type* pFrom)
{
return _Copy<destination_type>::copy(pTo, const_cast<source_type*>(pFrom));
}
}; // class GenericCopy
VCUE_Copy.h zawiera również następujące specjalizacje tej klasy: GenericCopy<BSTR>
, GenericCopy<VARIANT, BSTR>
, GenericCopy<BSTR, VARIANT>
. VCUE_CopyString.h zawiera specjalizacje kopiowania z pliku std::strings: GenericCopy<std::string>
, GenericCopy<VARIANT, std::string>
i GenericCopy<BSTR, std::string>
. Możesz ulepszyć GenericCopy
, dostarczając własne specjalizacje.
MapCopy
MapCopy
Przyjęto założenie, że skopiowane dane są przechowywane w standardowej mapie biblioteki języka C++, dzięki czemu można określić typ mapy, w której są przechowywane dane, oraz typ docelowy. Implementacja klasy używa tylko definicji typów dostarczonych przez klasę MapType , aby określić typ danych źródłowych i wywołać odpowiednią GenericCopy
klasę. Nie są potrzebne żadne specjalizacje tej klasy.
template <class MapType, class DestinationType = MapType::mapped_type>
class MapCopy
{
public :
typedef DestinationType destination_type;
typedef typename MapType::value_type source_type;
typedef MapType map_type;
typedef typename MapType::mapped_type pseudosource_type;
static void init(destination_type* p)
{
GenericCopy<destination_type, pseudosource_type>::init(p);
}
static void destroy(destination_type* p)
{
GenericCopy<destination_type, pseudosource_type>::destroy(p);
}
static HRESULT copy(destination_type* pTo, const source_type* pFrom)
{
return GenericCopy<destination_type, pseudosource_type>::copy(pTo, &(pFrom->second));
}
}; // class MapCopy
Zobacz też
Implementowanie kolekcji opartej na standardowej bibliotece C++
Przykład ATLCollections