ATL-Kopierrichtlinienklasse
Kopierrichtlinienklassen sind Hilfsklassen , die zum Initialisieren, Kopieren und Löschen von Daten verwendet werden. Mithilfe von Kopierrichtlinienklassen können Sie kopierende Semantik 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 in einer Kopierrichtlinienklasse erforderlichen Informationen, die als Vorlagenargument übergeben werden können, haben die ATL-Entwickler eine extreme Wiederverwendbarkeit dieser Klassen bereitgestellt. Wenn Sie beispielsweise eine Sammlung mit einem beliebigen Datentyp implementieren müssen, müssen Sie lediglich die entsprechende Kopierrichtlinie angeben. Sie müssen nie den Code berühren, der die Sammlung implementiert.
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, sollte die Verwendung der Klassen im ATL-Code die Typen einschränken, die sinnvoll sind. Wenn Sie beispielsweise eine Kopierrichtlinienklasse mit DER ATL-Auflistung oder Enumerationsimplementierung verwenden, muss es sich um einen Typ handeln, DestinationType
der als Parameter in einer COM-Schnittstellenmethode verwendet werden kann.
Verwenden Sie "init ", um Daten zu initialisieren, zu kopieren , um Daten zu kopieren und zu zerstören , um die Daten freizulassen. Die genaue Bedeutung der Initialisierung, des Kopierens und der Zerstörung sind die Aufgaben Standard der Kopierrichtlinienklasse und variieren je nach den beteiligten Datentypen.
Es gibt zwei Anforderungen für die Verwendung und Implementierung einer Kopierrichtlinienklasse:
Der erste zu kopierende Parameter darf nur einen Zeiger auf Daten empfangen, die Sie zuvor mit init initialisiert haben.
"destroy " darf niemals einen Zeiger auf Daten erhalten, die Sie zuvor mit init initialisiert oder per Kopie kopiert haben.
Standardimplementierungen
ATL stellt zwei Kopierrichtlinienklassen in Form der _Copy
Klassen und _CopyInterface
Vorlagen bereit:
Die
_Copy
Klasse ermöglicht das homogene Kopieren (keine Konvertierung zwischen Datentypen), da sie nur einen einzelnen Vorlagenparameter zum Angeben von beidenDestinationType
und "SourceType" bietet. Die generische Implementierung dieser Vorlage enthält keinen Initialisierungs- oder Zerstörungscode und verwendetmemcpy
zum Kopieren der Daten. ATL bietet außerdem Spezialisierungen für_Copy
VARIANT-, LPOLESTR-, OLEVERB- und CONNECTDATA-Datentypen.Die
_CopyInterface
Klasse stellt eine Implementierung zum Kopieren von Schnittstellenzeigern nach com-Standardregeln bereit. Erneut ermöglicht diese Klasse nur homogenes Kopieren, daher wird einfache Zuordnung und ein Aufruf zumAddRef
Ausführen der Kopie verwendet.
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 ATLCollections-Beispiel an. Diese Dateien enthalten zwei Richtlinienklassen GenericCopy
zum Kopieren von Vorlagen sowie MapCopy
eine Reihe von Spezialisierungen für verschiedene Datentypen GenericCopy
.
GenericCopy
GenericCopy
ermöglicht es Ihnen, den SourceType und DestinationType
als Vorlagenargumente anzugeben. Dies ist die allgemeinste Form der GenericCopy
Klasse aus 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önnen verbessern GenericCopy
, indem Sie weitere Spezialisierungen selbst anbieten.
MapCopy
MapCopy
geht davon aus, dass die kopierten Daten in einer C++-Standardbibliothekszuordnung gespeichert werden, sodass Sie den Zuordnungstyp angeben können, in dem die Daten gespeichert sind und der Zieltyp. Die Implementierung der Klasse verwendet lediglich die typedefs, die von der MapType-Klasse 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
Siehe auch
Implementieren einer auf der C++-Standardbibliothek basierten Auflistung
ATLCollections-Beispiel
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für