Поделиться через


Классы политики копирования ATL

Классы политики копирования — это служебные классы , используемые для инициализации, копирования и удаления данных. Классы политик копирования позволяют определять семантику копирования для любого типа данных и определять преобразования между различными типами данных.

ATL использует классы политик копирования в своих реализациях следующих шаблонов:

Инкапсулируя сведения, необходимые для копирования или преобразования данных в класс политики копирования, который можно передать в качестве аргумента шаблона, разработчики ATL предоставили крайнее повторное использование этих классов. Например, если необходимо реализовать коллекцию с помощью любого произвольного типа данных, необходимо указать соответствующую политику копирования; Вам никогда не нужно касаться кода, реализующего коллекцию.

Определение

По определению класс, предоставляющий следующие статические функции, является классом политики копирования:

static void init( DestinationType * p);

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

static void destroy( DestinationType * p);

Типы DestinationType и SourceType можно заменить произвольными типами данных для каждой политики копирования.

Примечание.

Хотя можно определить классы политик копирования для любых произвольных типов данных, использование классов в коде ATL должно ограничить типы, которые имеет смысл. Например, при использовании класса политики копирования с реализацией DestinationType коллекции или перечислителя ATL должен быть типом, который можно использовать в качестве параметра в методе COM-интерфейса.

Используйте init для инициализации данных, копирования данных и уничтожения для освобождения данных. Точное значение инициализации, копирования и уничтожения — это домен класса политики копирования и зависит от используемых типов данных.

Существует два требования к использованию и реализации класса политики копирования:

  • Первый параметр для копированиядолжен получать указатель только на данные, которые ранее инициализированы с помощью инициализации с помощью инициализации.

  • destroy должен получать только указатель на данные, которые вы ранее инициализировали с помощью инициализации или скопированного с помощью копирования.

Стандартные реализации

ATL предоставляет два класса политики копирования в виде классов шаблонов_Copy:_CopyInterface

  • Класс _Copy позволяет однородно копировать только (не преобразование между типами данных), так как он предлагает только один параметр шаблона для указания обоих DestinationType типов и SourceType. Универсальная реализация этого шаблона не содержит кода инициализации или уничтожения и используется memcpy для копирования данных. ATL также предоставляет специализации _Copy для типов данных VARIANT, LPOLESTR, OLEVERB и CONNECTDATA.

  • Класс _CopyInterface предоставляет реализацию для копирования указателей интерфейса в соответствии со стандартными правилами COM. Еще раз этот класс разрешает только однородное копирование, поэтому он использует простое назначение и вызов для AddRef выполнения копирования.

Пользовательские реализации

Как правило, необходимо определить собственные классы политик копирования для разнородного копирования (то есть преобразования между типами данных). В некоторых примерах пользовательских классов политик копирования просмотрите файлы VCUE_Copy.h и VCUE_CopyString.h в примере ATLCollections . Эти файлы содержат два класса политики копирования шаблонов, GenericCopy а MapCopyтакже ряд специализаций GenericCopy для разных типов данных.

GenericCopy

GenericCopy позволяет указать SourceType и DestinationType в качестве аргументов шаблона. Ниже приведена самая общая форма GenericCopy класса из 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 также содержит следующие специализации этого класса: GenericCopy<BSTR>, , GenericCopy<VARIANT, BSTR>GenericCopy<BSTR, VARIANT>. VCUE_CopyString.h содержит специализации для копирования из std::strings: GenericCopy<std::string>, GenericCopy<VARIANT, std::string>и GenericCopy<BSTR, std::string>. Вы можете улучшить GenericCopy , предоставив дополнительные специализации собственных.

MapCopy

MapCopy Предполагает, что копируемые данные хранятся в схеме стандартной библиотеки C++, поэтому позволяет указать тип карты, в которой хранятся данные и тип назначения. Реализация класса просто использует typedefs, предоставленные классом MapType , для определения типа исходных данных и вызова соответствующего GenericCopy класса. Специализации этого класса не требуются.

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

См. также

Реализация коллекции на основе стандартной библиотеки C++
Пример ATLCollections