Udostępnij za pośrednictwem


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 skopiowaniamusi 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 parametru DestinationType i SourceType. Ogólna implementacja tego szablonu nie zawiera kodu inicjalizacji ani zniszczenia i służy memcpy 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 do AddRef 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 MapCopywiele 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