Udostępnij przez


Klasy polityk kopiowania 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 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 _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 dla 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 AddRef w 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