Freigeben über


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 von DestinationType und SourceType bereitgestellt wird. Die generische Implementierung dieser Vorlage enthält keinen Initialisierungs- oder Zerstörungscode und verwendet memcpy, 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 von AddRef 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