STL/CLR-Container
Die STL/CLR-Bibliothek hat die gleichen Container, die in der C++-Standardbibliothek gefunden werden, wird jedoch in einer verwalteten Umgebung von .NET Framework ausgeführt.Wenn Sie bereits mit der Standardvorlagenbibliothek (STL) vertraut sind, wird STL/CLR die beste Methode fortzufahren, um die Fähigkeiten zu verwenden, die bereits während der Code in das Ziel aktualisieren die Common Language Runtime (CLR) entwickelt haben.
Dieses Dokument enthält eine Übersicht über die Container in STL/CLR, z. B. den Anforderungen für Containerelemente, welche Typen von Elementen, die in den Container eingefügt werden können, sowie die im Besitz Probleme im Zusammenhang mit mit den Elementen in den Containern.Gegebenenfalls werden die Unterschiede zwischen der systemeigenen und der Standardvorlagenbibliothek STL/CLR erwähnt.
Anforderungen für die Containerelemente
Alle Elemente, die in STL-Container eingefügt werden, müssen bestimmte Richtlinien befolgen.Weitere Informationen finden Sie unter Anforderungen für STL/CLR-Containerelemente.
Gültige Containerelemente
STL/CLR-Container können einen von zwei Typen Elemente enthalten:
Handles zu verweisen.
Referenztypen.
Nicht geschachtelte Werttypen.
Sie können geschachtelte Werttypen nicht in einem der STL/CLR-Container einfügen.
Handles für Verweistypen
Sie können ein Handle zu einem Referenztyp in einen STL/CLR-Container einfügen.Ein Handle in C++, die die CLR abzielt, ist ein Zeiger in systemeigenem C++ analog.Weitere Informationen finden Sie unter ^ (Handle für das Objekt für verwalteten Heap).
Beispiel
Im folgenden Beispiel wird gezeigt, wie ein Handle für einen Mitarbeiter Objekt in cliext::set einfügt.
// 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;
}
Verweistypen
Es ist auch möglich, einen Verweistyp (anstatt ein Handle zu einem Referenztyp) in einen STL/CLR-Container eingefügt werden soll.Der Hauptunterschied besteht darin, dass, wenn ein Container Verweistypen gelöscht wird, der Destruktor für alle inneren Elements aufgerufen wird, die Container.In einem Container Handles zu verweisen, würden die Destruktoren für diese Elemente nicht aufgerufen.
Beispiel
Im folgenden Beispiel wird gezeigt, wie ein Mitarbeiter Objekt in cliext::set einfügt.
// 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;
}
Nicht geschachtelte Werttypen
Sie können einen geschachtelten Werttyp in einen nicht CLR-Container/STL auch einfügen.Ein nicht geschachtelten Werttyp ist ein Werttyp, der nicht in einen Verweistyp geschachtelt wurde.
Ein Werttyp Element kann einer der Standardwert int sein, z. B. Typen, oder es kann ein benutzerdefinierter Werttyp, z. B. value class sein.Weitere Informationen finden Sie unter Classes and Structs (Managed)
Beispiel
Im folgenden Beispiel wird das erste Beispiel, indem Sie die Mitarbeiter Klasse einen Werttyp macht.Dieser Werttyp wird dann in cliext::set ebenso wie im ersten Beispiel eingefügt.
// 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;
}
Wenn Sie versuchen, ein Handle zu einem Werttyp in einen Container eingefügt werden soll, wird Compilerfehler C3225 generiert.
Leistungs-und Arbeitsspeicher-Auswirkungen
Sie müssen mehrere Faktoren berücksichtigen, ob beim Ermitteln von Handles für Verweistypen oder Werttypen als Containerelemente verwendet.Wenn Sie sich dafür entscheiden, um Werttypen verwenden, beachten Sie, dass eine Kopie des Elements eingefügt wird jedes Mal ein Element im Container erstellt wird.Für kleine Objekte sollte dies kein Problem darstellen, aber wenn die Objekte, die eingefügt werden, groß sind, litte Leistung verbessert werden.Wenn Sie Werttypen verwenden, ist es nicht möglich, ein Artikel in mehreren Containern gleichzeitig zu speichern, da jeder Container eine eigene Kopie des Elements hätte.
Wenn Sie sich dafür entscheiden, um Handles zu verweisen, verwenden Sie stattdessen möglicherweise eine höhere Leistung, da es nicht erforderlich ist, eine Kopie des Elements zu erstellen, wenn sie in den Container eingefügt wird.Auch Werttypen mit anderes als das gleiche Element kann in mehreren Containern befinden.Wenn Sie sich dafür entscheiden, um Handles zu verwenden, müssen Sie mach's am besten, um sicherzustellen, dass das Handle gültig ist und dass das Objekt, das er verweist, nicht an anderer Stelle im Programm gelöscht wurde.
Besitz-Probleme mit Containern
Container in STL/Werts zu CLR-Arbeit ist.Jedes Mal, wenn Sie ein Element in einen Container einfügen, wird eine Kopie dieses Elements eingefügt.Wenn Sie REFERENCE ähnliche Semantik abrufen möchten, können Sie ein Handle für ein Objekt statt das Objekt selbst einfügen.
Wenn Sie die Methode aufrufen oder Löschen eines Containers Handle Objekte löschen, werden die Objekte verweisen, die Handles nicht im Speicher freigegeben.Sie müssen entweder das Objekt löschen, oder explizit, da diese Objekte im verwalteten Heap befinden, können Sie dem Garbage Collector den Speicher freigibt, sobald er entscheidet, dass das Objekt nicht mehr verwendet wird.