Classes de stratégies de copie ATL
Les classes de stratégie de copie sont des classes utilitaires utilisées pour initialiser, copier et supprimer des données. Les classes de stratégie de copie vous permettent de définir la sémantique de copie pour n’importe quel type de données et de définir des conversions entre différents types de données.
ATL utilise des classes de stratégie de copie dans ses implémentations des modèles suivants :
En encapsulant les informations nécessaires pour copier ou convertir des données dans une classe de stratégie de copie qui peuvent être passées en tant qu’argument de modèle, les développeurs ATL ont permis un potentiel de réutilisation extrême de ces classes. Par exemple, si vous devez implémenter une collection à l’aide d’un type de données arbitraire, il vous suffit de fournir la stratégie de copie appropriée ; vous n’avez pas besoin de toucher au code qui implémente la collection.
Définition
Par définition, une classe qui fournit les fonctions statiques suivantes est une classe de stratégie de copie :
static void init(
DestinationType
* p);
static HRESULT copy(
DestinationType
* pTo, const
SourceType
* pFrom);
static void destroy(
DestinationType
* p);
Vous pouvez remplacer les types DestinationType
et SourceType par des types de données arbitraires pour chaque stratégie de copie.
Remarque
Bien que vous puissiez définir des classes de stratégie de copie pour tous les types de données arbitraires, l’utilisation des classes dans le code ATL doit limiter les types qui sont logiques. Par exemple, lors de l’utilisation d’une classe de stratégie de copie avec les implémentations de collection ou d’énumérateur ATL, DestinationType
doit être un type pouvant être utilisé comme paramètre dans une méthode d’interface COM.
Utilisez init pour initialiser des données, copier pour copier des données et détruire pour libérer les données. La signification précise de l’initialisation, de la copie et de la destruction est le domaine de la classe de stratégie de copie et varie en fonction des types de données impliqués.
Il existe deux exigences relatives à l’utilisation et à l’implémentation d’une classe de stratégie de copie :
Le premier paramètre à copier ne doit recevoir qu’un pointeur vers les données que vous avez précédemment initialisées à l’aide d’init.
détruire ne doit recevoir qu’un pointeur vers des données que vous avez précédemment initialisées à l’aide d’init ou copiées via copier.
Implémentations standard
ATL fournit deux classes de stratégie de copie sous la forme des classes de modèle _Copy
et _CopyInterface
:
La classe
_Copy
autorise uniquement la copie homogène (et non la conversion entre les types de données), car elle offre uniquement un seul paramètre de modèle pour spécifier à la foisDestinationType
et SourceType. L’implémentation générique de ce modèle ne contient aucun code d’initialisation ou de destruction et utilisememcpy
pour copier les données. ATL fournit également des spécialisations de_Copy
pour les types de données VARIANT, LPOLESTR, OLEVERB et CONNECTDATA.La classe
_CopyInterface
fournit une implémentation pour copier des pointeurs d’interface en suivant les règles COM standard. Une fois de plus, cette classe autorise uniquement la copie homogène, de sorte qu’elle utilise une affectation simple et un appel àAddRef
pour effectuer la copie.
Implémentations personnalisées
En règle générale, vous devrez définir vos propres classes de stratégie de copie pour la copie hétérogène (autrement dit, la conversion entre les types de données). Pour obtenir des exemples de classes de stratégie de copie personnalisées, examinez les fichiers VCUE_Copy.h et VCUE_CopyString.h dans l’exemple ATLCollections. Ces fichiers contiennent deux classes de stratégie de copie de modèle, GenericCopy
et MapCopy
, ainsi qu’un certain nombre de spécialisations de GenericCopy
pour différents types de données.
GenericCopy
GenericCopy
vous permet de spécifier les SourceType et DestinationType
en tant qu’arguments de modèle. Voici la forme la plus générale de la classe GenericCopy
de 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 contient également les spécialisations suivantes de cette classe : GenericCopy<BSTR>
, GenericCopy<VARIANT, BSTR>
, GenericCopy<BSTR, VARIANT>
. VCUE_CopyString.h contient des spécialisations pour la copie à partir de std ::strings : GenericCopy<std::string>
, GenericCopy<VARIANT, std::string>
et GenericCopy<BSTR, std::string>
. Vous pouvez améliorer GenericCopy
en fournissant vos propres spécialisations.
MapCopy
MapCopy
suppose que les données copiées sont stockées dans une carte de style bibliothèque standard C++, ce qui vous permet de spécifier le type de carte dans lequel les données sont stockées et le type de destination. L’implémentation de la classe utilise simplement les typesdefs fournis par la classe MapType pour déterminer le type des données sources et appeler la classe GenericCopy
appropriée. Aucune spécialisation de cette classe n’est nécessaire.
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
Voir aussi
Implémentation d’une collection basée sur la bibliothèque standard C++
Échantillon ATLCollections