Condividi tramite


Classi di criteri di copia ATL

Le classi dei criteri di copia sono classi di utilità usate per inizializzare, copiare ed eliminare dati. Le classi di criteri di copia consentono di definire la semantica di copia per qualsiasi tipo di dati e di definire conversioni tra tipi di dati diversi.

ATL usa classi di criteri di copia nelle implementazioni dei modelli seguenti:

Incapsulando le informazioni necessarie per copiare o convertire i dati in una classe di criteri di copia che può essere passata come argomento modello, gli sviluppatori ATL hanno fornito un'estrema riutilizzabilità di queste classi. Ad esempio, se è necessario implementare una raccolta usando qualsiasi tipo di dati arbitrario, è sufficiente fornire i criteri di copia appropriati; non è mai necessario toccare il codice che implementa la raccolta.

Definizione

Per definizione, una classe che fornisce le funzioni statiche seguenti è una classe di criteri di copia:

static void init( DestinationType * p);

static HRESULT copy( DestinationType * pTo, const SourceType * pFrom);

static void destroy( DestinationType * p);

È possibile sostituire i tipi DestinationType e SourceType con tipi di dati arbitrari per ogni criterio di copia.

Nota

Sebbene sia possibile definire classi di criteri di copia per qualsiasi tipo di dati arbitrario, l'uso delle classi nel codice ATL deve limitare i tipi che hanno senso. Ad esempio, quando si usa una classe di criteri di copia con le implementazioni dell'enumeratore o della raccolta ATL, DestinationType deve essere un tipo che può essere usato come parametro in un metodo di interfaccia COM.

Usare init per inizializzare i dati, copiare per copiare i dati e eliminare definitivamente i dati. Il significato preciso dell'inizializzazione, della copia e della distruzione è il dominio della classe dei criteri di copia e varia a seconda dei tipi di dati coinvolti.

Esistono due requisiti per l'uso e l'implementazione di una classe di criteri di copia:

  • Il primo parametro da copiare deve ricevere solo un puntatore ai dati inizializzati in precedenza tramite init.

  • l'eliminazione definitiva deve ricevere un puntatore ai dati inizializzati in precedenza usando init o copiati tramite copia.

Implementazioni standard

ATL fornisce due classi di criteri di copia sotto forma di _Copy classi modello e _CopyInterface :

  • La _Copy classe consente solo la copia omogenea (non la conversione tra tipi di dati) perché offre solo un singolo parametro di modello per specificare sia DestinationType che SourceType. L'implementazione generica di questo modello non contiene codice di inizializzazione o distruzione e usa memcpy per copiare i dati. ATL fornisce anche specializzazioni di _Copy per i tipi di dati VARIANT, LPOLESTR, OLEVERB e CONNECTDATA.

  • La _CopyInterface classe fornisce un'implementazione per la copia di puntatori di interfaccia seguendo le regole COM standard. Anche in questo caso questa classe consente solo la copia omogenea, quindi usa un'assegnazione semplice e una chiamata a per AddRef eseguire la copia.

Implementazioni personalizzate

In genere, è necessario definire classi di criteri di copia personalizzate per la copia eterogenea, ovvero la conversione tra tipi di dati. Per alcuni esempi di classi di criteri di copia personalizzate, esaminare i file VCUE_Copy.h e VCUE_CopyString.h nell'esempio ATLCollections . Questi file contengono due classi di criteri di copia modello e GenericCopy MapCopy, più una serie di specializzazioni di GenericCopy per tipi di dati diversi.

GenericCopy

GenericCopy consente di specificare SourceType e DestinationType come argomenti di modello. Ecco la forma più generale della GenericCopy classe da 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 contiene anche le specializzazioni seguenti di questa classe: GenericCopy<BSTR>, GenericCopy<VARIANT, BSTR>, GenericCopy<BSTR, VARIANT>. VCUE_CopyString.h contiene specializzazioni per la copia da std::strings: GenericCopy<std::string>, GenericCopy<VARIANT, std::string>e GenericCopy<BSTR, std::string>. È possibile migliorare GenericCopy fornendo ulteriori specializzazioni personalizzate.

MapCopy

MapCopy presuppone che i dati copiati vengano archiviati in una mappa in stile libreria standard C++, quindi consente di specificare il tipo di mappa in cui vengono archiviati i dati e il tipo di destinazione. L'implementazione della classe usa solo i typedef forniti dalla classe MapType per determinare il tipo dei dati di origine e per chiamare la classe appropriata GenericCopy . Non sono necessarie specializzazioni di questa classe.

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

Vedi anche

Implementazione di una raccolta basata su libreria standard C++
Esempio di ATLCollections