ATL のコピー ポリシー クラス
コピー ポリシー クラスは、データを初期化し、コピー、削除するために使用する ユーティリティ クラス です。コピー ポリシー クラスは、データの任意の型のコピーの意味を定義し、異なるデータ型の変換を定義できるようにします。
ATL は次のテンプレートの実装でコピー ポリシー クラスを使用します:
必要な情報をカプセル化してテンプレートの引数として渡すことができるコピー ポリシー データを ATL の開発者が提供するクラス。コピーまたは変換するには、これらのクラスに高い再利用性が。たとえば、任意のデータ型を使用してコレクションを実装する場合は、を指定する必要があるのは、適切なコピー ポリシーだけです。; はコレクションを実装するコードに接する必要はありません。
定義
定義上、次の静的関数を提供するクラスはコピー ポリシー クラスです:
static void init(DestinationType* p);
static HRESULT copy(DestinationType* pTo, const SourceType* pFrom);
static void destroy(DestinationType* p);
各コピー ポリシーの任意のデータ型と型 DestinationType と SourceType を 置き換えることができます。
[!メモ]
任意のデータ型のコピー ポリシー クラスを定義できますが、ATL コードのクラスは意味がある型を制限する必要があります。たとえば、ATL のコレクションまたは列挙子の実装でコピー ポリシー クラスを使用すると、DestinationType が COM インターフェイスのメソッドのパラメーターとして使用できる型である必要があります。
データ copy、および destroy をデータをデータを解放するためにコピーする初期化に init を使用します。初期化の正確な意味、コピー、および破棄はコピー ポリシー クラスのドメインで、関連するデータ型によって異なります。
コピー ポリシー クラスの使用と実装に 2 個の要件があります:
copy への最初のパラメーターは、initを使用する前に初期化済みデータへのポインターを受け取る場合のみする必要があります。
destroy は、init を使用する前に初期化または copyによってコピーされたデータへのポインターを受け取る場合のみする必要があります。
ストック実装
ATL は コピー(_C) と _CopyInterface テンプレート クラスの形式で 2 種類のコピー ポリシー クラスが用意されています:
_Copy のクラスは DestinationTypeSourceTypeとの両方を指定する単一のテンプレート パラメーターのみを提供するため、同種だけ使用すると、データ型間の変換できません)。このテンプレートの一般的な実装を初期化または破棄コードが含まれないため、データをコピーする memcpy を使用します。ATL は、VARIANT、LPOLESTR、OLEVERBと CONNECTDATA のデータ型に コピー(_C) の特殊化を提供します。
_CopyInterface のクラスは、標準の COM 規則に従ってインターフェイス ポインターをコピーする実装を提供します。再度このクラスは、同種だけに使用できますが、そのために AddRef 単純な割り当てとコピーを行うには、呼び出しを使用します。
カスタムの実装
通常、異種にコピーの独自のコピー ポリシー クラスを定義する必要があります (つまり、データ型の変換)。カスタム コピー ポリシー クラスの使用例については、" ATLCollections のサンプル ファイルの、VCUE_Copy.h と VCUE_CopyString.h を参照してください。これらのファイルには、2 種類のテンプレートのコピー ポリシー クラス GenericCopy、さまざまなデータ型の GenericCopy のいくつかの特殊な形式と MapCopyが含まれます。
GenericCopy
GenericCopy は、テンプレートの引数として SourceType と DestinationType を指定することができます。VCUE_Copy.h から GenericCopy のクラスの最も一般的な形式を次に示します:
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::stringは、からコピー用に特化したクラスです: GenericCopy<std::string>、GenericCopy<VARIANT, std::string>と GenericCopy<BSTR, std::string>。独自の特殊化によって GenericCopy を向上させることができます。
MapCopy
MapCopy データはコピーされませんが、STL スタイルのマップに格納されるため、データの格納先の型マッピングの種類を指定できますが、と仮定します。クラスの実装は、ソース データの型を決定し、GenericCopy の適切なクラスを呼び出すに MapType の クラスによって提供された typedef を使用します。このクラスの特殊化は必要ではありません。
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