STL/CLR コンテナー
STL/CLR ライブラリのに C++ の標準ライブラリに存在しますが、 .NET Framework のマネージ環境内で実行されます同じコンテナーがあります。既に標準テンプレート ライブラリ (STL) に慣れている場合は、 STL/CLR は、既に開発されたスキルを使用し続けるのに最適です。共通言語ランタイム (CLR) を対象とするコードをアップグレードしながら。
このドキュメントはコンテナー要素の要件など、 STL/CLR コンテナーの概要を、コンテナーに挿入できる所有権はコンテナー要素と表示要素の型提供します。適切な場合には、ネイティブ標準テンプレート ライブラリと STL/CLR の違いは説明します。
コンテナー要素の必要条件
STL コンテナーに挿入されるすべての要素は、特定のガイドラインに従う必要があります。詳細については、「STL/CLR コンテナー要素の要件」を参照してください。
有効なコンテナー要素
STL/CLR コンテナーは、要素の 2 種類の 1 つを保留できます:
参照型へのハンドル。
参照型
ボックス化解除された値型。
STL/CLR コンテナーにボックス化された値型を挿入できません。
参照型へのハンドル
STL/CLR コンテナーに参照型にハンドルを挿入できます。CLR を対象とする C++ のハンドルはネイティブ C++ のポインターに類似しています。詳細については、「オブジェクト演算子 (^) へのハンドル (C++ コンポーネント拡張)」を参照してください。
例
次の例に cliext::set、従業員のオブジェクトへのハンドルを挿入する方法を示しています。
// cliext_container_valid_reference_handle.cpp
// compile with: /clr
#include <cliext/set>
using namespace cliext;
using namespace System;
ref class Employee
{
public:
// STL containers might require a public constructor, so it
// is a good idea to define one.
Employee() :
name(nullptr),
employeeNumber(0) { }
// All STL containers require a public copy constructor.
Employee(const Employee% orig) :
name(orig.name),
employeeNumber(orig.employeeNumber) { }
// All STL containers require a public assignment operator.
Employee% operator=(const Employee% orig)
{
if (this != %orig)
{
name = orig.name;
employeeNumber = orig.employeeNumber;
}
return *this;
}
// All STL containers require a public destructor.
~Employee() { }
// Associative containers such as maps and sets
// require a comparison operator to be defined
// to determine proper ordering.
bool operator<(const Employee^ rhs)
{
return (employeeNumber < rhs->employeeNumber);
}
// The employee's name.
property String^ Name
{
String^ get() { return name; }
void set(String^ value) { name = value; }
}
// The employee's employee number.
property int EmployeeNumber
{
int get() { return employeeNumber; }
void set(int value) { employeeNumber = value; }
}
private:
String^ name;
int employeeNumber;
};
int main()
{
// Create a new employee object.
Employee^ empl1419 = gcnew Employee();
empl1419->Name = L"Darin Lockert";
empl1419->EmployeeNumber = 1419;
// Add the employee to the set of all employees.
set<Employee^>^ emplSet = gcnew set<Employee^>();
emplSet->insert(empl1419);
// List all employees of the company.
for each (Employee^ empl in emplSet)
{
Console::WriteLine("Employee Number {0}: {1}",
empl->EmployeeNumber, empl->Name);
}
return 0;
}
参照型
(参照型へのハンドルはなく STL/CLR コンテナーに参照型を挿入することもできます。次の主な違いは、参照型のコンテナーが削除されると、デストラクターはコンテナーすべての要素の内部に対して呼び出されます。参照型へのハンドル コンテナーで、これらの要素のデストラクターは呼び出されません。
例
次の例に cliext::set、従業員のオブジェクトを挿入する方法を示しています。
// cliext_container_valid_reference.cpp
// compile with: /clr
#include <cliext/set>
using namespace cliext;
using namespace System;
ref class Employee
{
public:
// STL containers might require a public constructor, so it
// is a good idea to define one.
Employee() :
name(nullptr),
employeeNumber(0) { }
// All STL containers require a public copy constructor.
Employee(const Employee% orig) :
name(orig.name),
employeeNumber(orig.employeeNumber) { }
// All STL containers require a public assignment operator.
Employee% operator=(const Employee% orig)
{
if (this != %orig)
{
name = orig.name;
employeeNumber = orig.employeeNumber;
}
return *this;
}
// All STL containers require a public destructor.
~Employee() { }
// Associative containers such as maps and sets
// require a comparison operator to be defined
// to determine proper ordering.
bool operator<(const Employee^ rhs)
{
return (employeeNumber < rhs->employeeNumber);
}
// The employee's name.
property String^ Name
{
String^ get() { return name; }
void set(String^ value) { name = value; }
}
// The employee's employee number.
property int EmployeeNumber
{
int get() { return employeeNumber; }
void set(int value) { employeeNumber = value; }
}
private:
String^ name;
int employeeNumber;
};
int main()
{
// Create a new employee object.
Employee empl1419;
empl1419.Name = L"Darin Lockert";
empl1419.EmployeeNumber = 1419;
// Add the employee to the set of all employees.
set<Employee>^ emplSet = gcnew set<Employee>();
emplSet->insert(empl1419);
// List all employees of the company.
for each (Employee^ empl in emplSet)
{
Console::WriteLine("Employee Number {0}: {1}",
empl->EmployeeNumber, empl->Name);
}
return 0;
}
ボックス化解除された値型
STL/CLR、コンテナーにボックス化解除された値型を挿入できます。ボックス化解除された値型は参照型に 囲まれなかった 値型です。
値型の要素が標準値型は 1、 intなどであることも、 value classなどのユーザー定義の値型でもかまいません。詳細については、「クラスと構造体 (C++ コンポーネント拡張)」を参照してください。
例
次の例では、従業員のクラスに値型を表示することによって、最初の例を変更します。この値型は最初の例のように cliext::set にこの場合、挿入されます。
// cliext_container_valid_valuetype.cpp
// compile with: /clr
#include <cliext/set>
using namespace cliext;
using namespace System;
value class Employee
{
public:
// Associative containers such as maps and sets
// require a comparison operator to be defined
// to determine proper ordering.
bool operator<(const Employee^ rhs)
{
return (employeeNumber < rhs->employeeNumber);
}
// The employee's name.
property String^ Name
{
String^ get() { return name; }
void set(String^ value) { name = value; }
}
// The employee's employee number.
property int EmployeeNumber
{
int get() { return employeeNumber; }
void set(int value) { employeeNumber = value; }
}
private:
String^ name;
int employeeNumber;
};
int main()
{
// Create a new employee object.
Employee empl1419;
empl1419.Name = L"Darin Lockert";
empl1419.EmployeeNumber = 1419;
// Add the employee to the set of all employees.
set<Employee>^ emplSet = gcnew set<Employee>();
emplSet->insert(empl1419);
// List all employees of the company.
for each (Employee empl in emplSet)
{
Console::WriteLine("Employee Number {0}: {1}",
empl.EmployeeNumber, empl.Name);
}
return 0;
}
コンテナーに値型へのハンドルを挿入しようとすると コンパイラ エラー C3225 が生成されます。
パフォーマンスとメモリ影響
かどうかを調べるときにはコンテナー要素として参照型と値型へのハンドルを使用するために複数の点を考慮してください。値型を使用する場合は要素のコピーがコンテナーに要素に挿入されるたびに作成されることに注意してください。小さなオブジェクトの場合、これは問題ではありません。挿入されたオブジェクトが大きいとパフォーマンスが低下する可能性があります。各コンテナーが要素の独自のコピーを持つため、値型を使用すると、複数のコンテナーに 1 個の要素を同時に保存することは不可能です。
参照型にハンドルを使用すると、パフォーマンスはコンテナーに挿入されると要素のコピーを作成する必要がないため、かかることがあります。また、値型とは異なり、同じ要素は複数のコンテナーに含めることができます。ただし、ハンドルを使用する場合、ハンドルが有効であること、および確認する対策を講じて、プログラムで削除されていないことを参照するオブジェクトできます。
コンテナーがあります。所有権の問題
値のセマンティクスの STL/CLR 作業のコンテナー。コンテナーに要素を挿入するたびに、その要素のコピーが挿入されます。参照と同様のセマンティクスを取得するには、オブジェクト自体ではなく、オブジェクトへのハンドルを挿入できます。
オフをダイヤルするか、ハンドルのオブジェクトのコンテナーのメソッドを消去するときに、ハンドルが参照するオブジェクトがメモリから解放されません。明示的にオブジェクトを削除するか、これらのオブジェクトがマネージ ヒープに存在するため、オブジェクトは使用しなくなったと判断した場合、ガベージ コレクターがメモリを解放するようにします。