Conteneurs STL/CLR
La bibliothèque STL/CLR a les mêmes conteneurs qui sont détectés dans la bibliothèque C++ standard, mais il fonctionne dans l'environnement managé.NET Framework.Si vous êtes déjà familiarisé avec la bibliothèque de modèles Standard (STL), STL/CLR est le meilleur moyen de continuer à utiliser des compétences que vous avez déjà développées pendant la mise à niveau votre code pour cibler le common langage (CLR) runtime.
Ce document fournit une vue d'ensemble des conteneurs dans STL/CLR, tel que les spécifications des éléments conteneur, les types d'éléments que vous pouvez insérer dans les conteneurs, et la propriété publie avec les éléments des conteneurs.Le cas échéant, les différences entre la bibliothèque de modèles Standard et le STL/CLR natifs sont indiquées.
Spécifications pour les éléments conteneurs
Tous les éléments insérés dans des conteneurs STL doivent exécution certaines règles.Pour plus d'informations, consultez Spécifications pour les éléments de conteneur STL/CLR.
Éléments conteneurs valides
Les conteneurs STL/CLR peuvent contenir un des deux types d'éléments :
Handles aux types référence.
Types référence.
Types valeur unboxed.
Vous ne pouvez pas insérer des types valeur boxed dans les conteneurs STL/CLR de l'ordinateur.
Handles aux types référence
Vous pouvez insérer un handle vers un type référence dans un conteneur STL/CLR.Un handle en C++ qui cible le CLR est analogue à un pointeur en C++ natif.Pour plus d'informations, consultez Handle sur l'opérateur Object (^) (extensions du composant C++).
Exemple
L'exemple suivant indique comment insérer un handle vers un objet employee dans 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;
}
Types référence
Il est également possible d'insérer un type référence (plutôt qu'un handle vers un type référence) dans un conteneur STL/CLR.La principale différence ici est que lorsqu'un conteneur de types référence est supprimé, le destructeur est appelé pour tout l'intérieur d'éléments qui conteneur.Dans un conteneur de handles aux types référence, les destructeurs pour ces éléments ne seraient pas appelés.
Exemple
L'exemple suivant indique comment insérer un objet employee dans 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;
}
Types valeur unboxed
Vous pouvez également insérer un type valeur unboxed dans un conteneur STL/CLR.Un type valeur unboxed est un type valeur qui n'a pas été convertie dans un type référence.
Un élément de type valeur peut être l'un des types valeur standard, par exemple int, ou peut être un type valeur défini par l'utilisateur, comme value class.Pour plus d'informations, consultez Classes et structs (extensions du composant C++).
Exemple
L'exemple suivant modifie le premier exemple en transformant la classe employee un type valeur.Ce type valeur est ensuite inséré dans cliext::set comme dans le premier exemple.
// 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;
}
Si vous essayez d'insérer un handle vers un type valeur dans un conteneur, Erreur du compilateur C3225 est généré.
Conséquences et de mémoire
Vous devez considérer plusieurs facteurs en déterminant si les handles aux types référence ou des types valeur comme éléments conteneur.Si vous décidez d'utiliser des types valeur, n'oubliez pas qu'une copie de l'élément est créée chaque fois qu'un élément est insérée dans le conteneur.Pour les petits objets, cela ne doit pas être un problème, mais si les objets sont insérés sont volumineux, les performances peuvent souffrir.De plus, si vous utilisez des types valeur, il est impossible d'enregistrer un élément dans plusieurs conteneurs en même temps donné que chaque conteneur aura sa propre copie de l'élément.
Si vous décidez d'utiliser des handles aux types référence à la place, les performances peuvent augmenter car il n'est pas nécessaire de faire une copie de l'élément lorsqu'il est inséré dans le conteneur.En outre, contrairement aux types valeur, le même élément peut exister dans plusieurs conteneurs.Toutefois, si vous décidez d'utiliser des handles, vous devez veiller à garantir que le handle est valide et que l'objet qu'il fasse référence n'a pas été supprimé ailleurs dans le programme.
Problèmes de propriétés avec des conteneurs
Conteneurs dans le travail de STL/CLR sur la sémantique de valeur.Chaque fois que vous insérez un élément dans un conteneur, une copie de cet élément est insérée.Si vous souhaitez obtenir la sémantique comme une référence, vous pouvez insérer un handle vers un objet plutôt que l'objet lui-même.
Lorsque vous appelez l'espace libre ou effacer la méthode du conteneur d'objets de handles, les objets à que les handles font référence ne sont pas récupérés de la mémoire.Vous devez ou supprimer explicitement l'objet, ou, car ces objets résident sur le tas managé, activez le garbage collector de libérer la mémoire une fois qu'elle détermine que l'objet n'est plus utilisé.