Partilhar via


Classes de política de cópia ATL

As classes de política de cópia são classes de utilitário usadas para inicializar, copiar e excluir dados. As classes de política de cópia permitem definir semântica de cópia para qualquer tipo de dados e conversões entre diferentes tipos de dados.

A ATL usa classes de política de cópia em suas implementações dos seguintes modelos:

Ao encapsular as informações necessárias para copiar ou converter dados em uma classe de política de cópia que pode ser passada como um argumento de modelo, os desenvolvedores da ATL forneceram extrema reutilização dessas classes. Por exemplo, se você precisar implementar uma coleção usando qualquer tipo de dados arbitrário, tudo o que você precisa fornecer é a política de cópia apropriada; você nunca precisa tocar no código que implementa a coleção.

Definição

Por definição, uma classe que fornece as seguintes funções estáticas é uma classe de política de cópia:

static void init( DestinationType * p);

static HRESULT copy( DestinationType * pTo, const SourceType * pFrom);

static void destroy( DestinationType * p);

Você pode substituir os tipos DestinationType e SourceType por tipos de dados arbitrários para cada política de cópia.

Observação

Embora você possa definir classes de política de cópia para quaisquer tipos de dados arbitrários, o uso das classes no código ATL deve limitar os tipos que fazem sentido. Por exemplo, quando se usa uma política de cópia com coleções da ATL ou implementações de enumeradores, DestinationType deve ser um tipo que pode ser usado como parâmetro num método de interface COM.

Use init para inicializar dados, copiar para copiar dados e destruir para liberar os dados. O significado exato de inicialização, cópia e destruição é o domínio da classe de política de cópia e variará dependendo dos tipos de dados envolvidos.

Há dois requisitos sobre o uso e a implementação de uma classe de política de cópia:

  • O primeiro parâmetro para copy deve receber apenas um ponteiro para dados que tenhas inicializado anteriormente usando init.

  • destroy só deve receber um ponteiro para dados que tenha inicializado anteriormente usando init ou copiado via copy.

Implementações padrão

ATL fornece duas classes de política de cópia na forma das classes de modelo _Copy e _CopyInterface:

  • A _Copy classe permite apenas cópia homogênea (não conversão entre tipos de dados), uma vez que oferece apenas um único parâmetro de modelo para especificar ambos DestinationType e SourceType. A implementação genérica deste modelo não contém nenhum código de inicialização ou destruição e usa memcpy para copiar os dados. A ATL também fornece especializações para os tipos de dados _Copy VARIANT, LPOLESTR, OLEVERB e CONNECTDATA.

  • A _CopyInterface classe fornece uma implementação para copiar ponteiros de interface seguindo regras COM padrão. Mais uma vez, essa classe permite apenas a cópia homogênea, por isso usa uma atribuição simples e uma chamada para AddRef executar a cópia.

Implementações personalizadas

Normalmente, você precisará definir suas próprias classes de política de cópia para cópia heterogênea (ou seja, conversão entre tipos de dados). Para obter alguns exemplos de classes de política de cópia personalizadas, examine os arquivos VCUE_Copy.h e VCUE_CopyString.h no exemplo ATLCollections . Esses ficheiros contêm duas classes GenericCopy e MapCopy de política de cópia de modelo, além de várias especializações de GenericCopy para diferentes tipos de dados.

Reprodução Genérica

GenericCopy permite que você especifique o SourceType e DestinationType como argumentos de modelo. Aqui está a forma mais geral da GenericCopy classe 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 também contém as seguintes especializações desta classe: GenericCopy<BSTR>, GenericCopy<VARIANT, BSTR>, GenericCopy<BSTR, VARIANT>. VCUE_CopyString.h contém especializações para cópia de std::strings: GenericCopy<std::string>, GenericCopy<VARIANT, std::string>, e GenericCopy<BSTR, std::string>. Você pode melhorar GenericCopy fornecendo mais especializações próprias.

MapCopy

MapCopy pressupõe que os dados que estão sendo copiados são armazenados em um mapa no estilo de biblioteca padrão C++, portanto, permite especificar o tipo de mapa no qual os dados são armazenados e o tipo de destino. A implementação da classe apenas usa os typedefs fornecidos pela classe MapType para determinar o tipo dos dados de origem e chamar a classe apropriada GenericCopy . Não são necessárias especializações desta 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

Ver também

Implementando uma coleção de Library-Based padrão C++
Amostra ATLCollections