Classes de diretiva de impressão de ATL
As classes de diretiva de impressão são classes utilitárias usado para inicializar, copiar, e excluir dados.As classes de diretiva de impressão permitem que você defina a semântica de impressão para qualquer tipo de dados, e defina conversões entre tipos de dados diferentes.
Usos de ATL copia classes da diretiva nas implementações dos seguintes modelos:
Encapsulando as informações necessárias para copiar ou converter dados em uma classe de diretiva de impressão que pode ser passada como um argumento de modelo, os desenvolvedores de ATL previram reusabilidade extremos de essas classes.Por exemplo, se você precisará implementar uma coleção usando qualquer tipo de dados arbitrário, tudo o que você precisa fornecer é a diretiva apropriada de impressão; você nunca tem que 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 diretiva de impressão:
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 com tipos de dados arbitrários para cada diretiva de impressão.
Observação |
---|
Embora você possa definir a política de impressão classes para quaisquer tipos de dados arbitrários, use as classes no código de ATL deve limitar os tipos que fazem sentido.Por exemplo, ao usar uma classe de diretiva de impressão com implementações de coleção ou o enumerador de ATL, DestinationType deve ser um tipo que pode ser usado como um parâmetro para um método da interface COM. |
Use init para inicializar dados, copy para copiar dados, e destroy para liberar os dados.O significado preciso de inicialização, copiar, e destruindo são o domínio da classe da diretiva de impressão e irá variar dependendo dos tipos de dados envolvidos.
Há dois requisitos em uso e na implementação de uma classe de diretiva de impressão:
O primeiro parâmetro a copy só deve receber um ponteiro para os dados que você tenha inicializadas anteriormente usando init.
destroy somente nunca deve receber um ponteiro para os dados que você tenha inicializado usando init ou tem copiado anteriormente através de copy.
Implementações padrão
ATL fornece duas classes de diretiva de impressão na forma de classes do modelo de _Copiar e de _CopyInterface :
A classe de _Copiar permite copiar homogêneo (não apenas conversão entre tipos de dados) desde que oferece apenas um único parâmetro do modelo especificar DestinationType e SourceType.A implementação genérico este modelo não contém nenhum código de inicialização ou destruição e usa memcpy para copiar os dados.ATL também fornece especializações de _Copiar para VARIANT, LPOLESTR, tipos de dados de OLEVERB, e de CONNECTDATA .
A classe de _CopyInterface fornece uma implementação para copiar ponteiros de interface após as regras padrão COM.Mais uma vez esta classe permite somente copiar homogêneo, para que usa a atribuição simples e uma chamada para AddRef para executar a cópia.
Implementações personalizadas
Normalmente, você precisará definir suas próprias classes de política para copiar heterogêneo (isto é, conversão entre tipos de dados).Para alguns exemplos de classes personalizadas da diretiva de impressão, examine os arquivos VCUE_Copy.h e VCUE_CopyString.h no exemplo de ATLCollections .Esses arquivos contêm duas classes de diretiva de impressão do modelo, GenericCopy e MapCopy, mais um número de especializações de GenericCopy para diferentes tipos de dados.
GenericCopy
GenericCopy permite que você especifique o SourceType e DestinationType como argumentos de modelo.Aqui é a forma mais geral da classe de 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 também contém as seguintes especializações de essa classe: GenericCopy<BSTR>, GenericCopy<VARIANT, BSTR>, GenericCopy<BSTR, VARIANT>.VCUE_CopyString.h contém especializações para copiar std::stringde s: GenericCopy<std::string>, GenericCopy<VARIANT, std::string>, e GenericCopy<BSTR, std::string>.Você pode aprimorar GenericCopy fornecendo uma especializações adicionais de sua preferência.
MapCopy
MapCopy assume que os dados que estão sendo copiados serão armazenados em um mapa de STL- estilo, para que permitem que você especifique o tipo de mapa em que os dados são armazenados e o tipo de destino.A implementação da classe usa apenas os typedefs fornecido pela classe de MapType para determinar o tipo de dados de origem e chame a classe apropriada de GenericCopy .Nenhuma especialização de essa classe é necessária.
template <class MapType, class DestinationType = MapType::referent_type>
class MapCopy
{
public :
typedef DestinationType destination_type;
typedef typename MapType::value_type source_type;
typedef MapType map_type;
typedef typename MapType::referent_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