Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
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 DestinationType i Typ źródła można zastąpić dowolnymi typami danych dla każdej zasady kopiowania.
Uwaga / Notatka
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, gdy używa się klasy strategii kopiowania wraz z implementacjami kolekcji lub modułu wyliczającego ATL, DestinationType musi być typem, który można użyć jako parametr w metodzie interfejsu COM.
Użyj init do inicjalizacji danych, copy do kopiowania danych, a destroy do zwolnienia danych. 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 funkcji copy powinien otrzymywać wskaźnik tylko do danych, które uprzednio zainicjowałeś za pomocą init.
destroy powinien zawsze otrzymywać wskaźnik do danych, które zainicjowałeś wcześniej za pomocą init lub skopiowałeś za pomocą copy.
Implementacje standardowe
Usługa ATL udostępnia dwie klasy zasad kopiowania w postaci klas szablonów _Copy i :_CopyInterface
Klasa
_Copyumożliwia kopiowanie homogeniczne (nie konwersję między typami danych), ponieważ oferuje tylko jeden parametr szablonu do określenia parametruDestinationTypei SourceType. Ogólna implementacja tego szablonu nie zawiera kodu inicjalizacji ani zniszczenia i służymemcpydo kopiowania danych. ATL udostępnia również specjalizacje_Copydla typów danych VARIANT, LPOLESTR, OLEVERB i CONNECTDATA.Klasa
_CopyInterfacezapewnia 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łaniaAddRefw celu dokonania 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: GenericCopy i MapCopy, a także wiele specjalizacji GenericCopy dla różnych typów danych.
KopiaOgólna
GenericCopy umożliwia określenie 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 także
Implementowanie standardowej kolekcji Library-Based języka C++
Przykład ATLCollections