ATL-Kopierrichtlinienklasse
Kopierrichtlinienklassen sind Hilfsklassen zum Initialisieren, Kopieren und Löschen von Daten. Mithilfe von Kopierrichtlinienklassen können Sie Kopiersemantik für jeden Datentyp definieren und Konvertierungen zwischen verschiedenen Datentypen definieren.
ATL verwendet Kopierrichtlinienklassen in den Implementierungen der folgenden Vorlagen:
Durch die Kapselung der zum Kopieren oder Konvertieren von Daten erforderlichen Informationen in einer Kopierrichtlinienklasse, die als Vorlagenargument übergeben werden kann, haben die ATL-Entwickler eine extreme Wiederverwendbarkeit dieser Klassen erreicht. Wenn Sie beispielsweise eine Sammlung mit einem beliebigen Datentyp implementieren müssen, müssen Sie lediglich die entsprechende Kopierrichtlinie angeben. Den Code, der die Sammlung implementiert, können Sie unberührt lassen.
Definition
Standardmäßig ist eine Klasse, die die folgenden statischen Funktionen bereitstellt, eine Kopierrichtlinienklasse:
static void init(
DestinationType
* p);
static HRESULT copy(
DestinationType
* pTo, const
SourceType
* pFrom);
static void destroy(
DestinationType
* p);
Sie können die Typen DestinationType
und SourceType durch beliebige Datentypen für jede Kopierrichtlinie ersetzen.
Hinweis
Obwohl Sie Kopierrichtlinienklassen für beliebige Datentypen definieren können, schränken die Klassen im ATL-Code die Typen auf die sinnvollen ein. Wenn Sie beispielsweise eine Kopierrichtlinienklasse mit der Auflistung oder Enumerationsimplementierung von ATL verwenden, muss DestinationType
ein Typ sein, der als Parameter in einer COM-Schnittstellenmethode verwendet werden kann.
Verwenden Sie init, um Daten zu initialisieren, copy zum Kopieren von Daten und destroy zum Freigeben der Daten. Die genaue Bedeutung der Initialisierung, des Kopierens und der Zerstörung ist die Domäne der Kopierrichtlinienklasse und variiert je nach den beteiligten Datentypen.
Es gibt zwei Anforderungen für die Verwendung und Implementierung einer Kopierrichtlinienklasse:
Der erste Parameter für copy darf nur einen Zeiger auf Daten empfangen, die Sie zuvor mit init initialisiert haben.
destroy darf nur einen Zeiger auf Daten empfangen, die Sie zuvor mit init initialisiert oder über copy kopiert haben.
Standardimplementierungen
ATL stellt zwei Kopierrichtlinienklassen in Form der Vorlagenklassen _Copy
und _CopyInterface
bereit:
Die
_Copy
-Klasse ermöglicht das homogene Kopieren (nicht die Konvertierung zwischen Datentypen), da nur ein einzelner Vorlagenparameter zum Angeben vonDestinationType
und SourceType bereitgestellt wird. Die generische Implementierung dieser Vorlage enthält keinen Initialisierungs- oder Zerstörungscode und verwendetmemcpy
, um die Daten zu kopieren. ATL bietet außerdem Spezialisierungen von_Copy
für die Datentypen VARIANT, LPOLESTR, OLEVERB und CONNECTDATA.Die
_CopyInterface
-Klasse stellt eine Implementierung zum Kopieren von Schnittstellenzeigern nach Standard-COM-Regeln bereit. Auch diese Klasse ermöglicht nur homogenes Kopieren, sodass einfache Zuordnung und ein Aufruf vonAddRef
zum Ausführen der Kopie verwendet werden.
Benutzerdefinierte Implementierungen
In der Regel müssen Sie Ihre eigenen Kopierrichtlinienklassen für heterogenes Kopieren (d. h. Konvertierung zwischen Datentypen) definieren. Sehen Sie sich einige Beispiele für benutzerdefinierte Kopierrichtlinienklassen in den Dateien VCUE_Copy.h und VCUE_CopyString.h im Beispiel ATLCollections an. Diese Dateien enthalten zwei Richtlinienklassen zum Kopieren von Vorlagen, GenericCopy
und MapCopy
, sowie eine Reihe von Spezialisierungen von GenericCopy
für verschiedene Datentypen.
GenericCopy
Mit GenericCopy
können Sie SourceType und DestinationType
als Vorlagenargumente angeben. Dies ist die allgemeinste Form der GenericCopy
-Klasse von 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 enthält auch die folgenden Spezialisierungen dieser Klasse: GenericCopy<BSTR>
, GenericCopy<VARIANT, BSTR>
, GenericCopy<BSTR, VARIANT>
. VCUE_CopyString.h enthält Spezialisierungen zum Kopieren aus std::strings: GenericCopy<std::string>
, GenericCopy<VARIANT, std::string>
und GenericCopy<BSTR, std::string>
. Sie könnten GenericCopy
verbessern, indem Sie eigene Spezialisierungen anbieten.
MapCopy
MapCopy
geht davon aus, dass die kopierten Daten in einer C++-Standardbibliothekszuordnung gespeichert werden, sodass Sie den Typ der Zuordnung angeben können, in der die Daten gespeichert sind, und den Zieltyp. Die Implementierung der Klasse verwendet nur die typedefs, die von der Klasse MapType bereitgestellt werden, um den Typ der Quelldaten zu bestimmen und die entsprechende GenericCopy
-Klasse aufzurufen. Es sind keine Spezialisierungen dieser Klasse erforderlich.
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
Weitere Informationen
Implementieren einer auf der C++-Standardbibliothek basierten Auflistung
ATLCollections-Beispiel