Классы политики копирования 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