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 siaDestinationType
che SourceType. L'implementazione generica di questo modello non contiene codice di inizializzazione o distruzione e usamemcpy
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 perAddRef
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