STL/CLR – kontejnery
Knihovna STL/CLR má kontejnerů, které se nacházejí ve standartní knihovny jazyka C++, ale běží v rámci spravované prostředí rozhraní.NET Framework.Pokud jste již obeznámeni s šablonu knihovny STL (Standard), STL/CLR je nejlepší způsob, jak používat dovednosti, které jste již vytvořili při upgradu kódu k cíli společný jazykový modul runtime (CLR).
Tento dokument obsahuje přehled kontejnerů v STL/CLR, například požadavky na elementy typu kontejner, typy prvků, že můžete vložit do nádoby a vlastnictví problémy s prvky v kontejnerech.V případě potřeby jsou uvedeny rozdíly mezi nativní knihovny standardních šablon a STL/CLR.
Požadavky na prvky kontejneru
Všechny prvky, které jsou zařazeny do STL kontejnery musí dodržovat určitá pravidla.Další informace naleznete v tématu Požadavky na elementy kontejnerů STL/CLR.
Elementy typu kontejner platné
Kontejnerů STL/CLR mohou obsahovat jednu ze dvou typů prvků:
Zpracovává pro referenční typy.
Referenční typy.
Hodnota typů.
Zabalené typy hodnot nelze vložit do libovolného kontejnerů STL/CLR.
Úchyty pro odkazové typy
Popisovač k typu odkazu můžete vložit do kontejneru STL/CLR.V jazyce C++ pro CLR popisovače je analogický ukazatel v nativní C++.Další informace naleznete v tématu Operátor popisovače objektu (^) (rozšíření komponent C++).
Příklad
Následující příklad ukazuje, jak vložit popisovač k objektu zaměstnance do 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;
}
Odkazové typy
Také je možné vložit do nádoby STL/CLR typ odkazu (nikoli popisovač k typu odkazu).Hlavní rozdíl je, že při odstranění kontejneru typy odkazů je zavolán destruktor pro všechny prvky uvnitř tohoto kontejneru.V nádobě úchyty pro odkazové typy by jen destruktory pro tyto prvky.
Příklad
Následující příklad ukazuje, jak vložit objekt do zaměstnance 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;
}
Hodnota typů
Hodnota typu můžete také vložit do kontejneru STL/CLR.Typ hodnota je hodnotový typ, který nebyl do na typ odkazu.
Typ prvku hodnota může být jeden z typů standardní hodnota, jako int, nebo může být hodnota definovaná uživatelem typu, jako value class.Další informace naleznete v tématu Třídy a struktury (rozšíření komponent C++)
Příklad
Následující příklad upravuje první příklad tím, že zaměstnanec třídy typu hodnoty.Tento typ hodnoty je pak vložen do cliext::set stejně jako v prvním příkladu.
// 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;
}
Pokud se pokusíte vložit popisovač typu hodnoty do nádoby, Chyba kompilátoru C3225 je generován.
Výkon a paměti důsledky
Při určování, zda chcete použít úchyty pro referenční typy nebo typy hodnot jako elementy typu kontejner, je nutné zvážit několik faktorů.Pokud se rozhodnete použít typy hodnot, mějte na paměti, že pokaždé, když prvek je vložen do kontejneru je vytvořena kopie prvku.Pro malé objekty to by neměl být problém, ale pokud vkládaný objekty jsou velké, může zhoršení výkonu.Pokud používáte typy hodnot, je také možné uložit jeden prvek do více nádob ve stejnou dobu, protože každá nádoba má svou vlastní kopii prvku.
Pokud se rozhodnete namísto referenční typy pomocí táhel, může zvýšit výkon vzhledem k tomu, že je nezbytné vytvořit kopii prvku při vložení do kontejneru.Také na rozdíl od s hodnotovými typy téhož prvku mohou existovat ve více kontejnerů.Ale pokud se rozhodnete použít úchyty, je pečlivě Ujistěte se, že popisovač je platný a zda objekt, který odkazuje na nebyla odstraněna jinde v programu.
Vlastnictví problémy s kontejnery
Kontejnery v STL/CLR pracovat na hodnotu sémantiku.Pokaždé, když vložíte prvek do nádoby, je vložena kopie daného prvku.Pokud chcete získat sémantiku jako odkaz, můžete vložit popisovač k objektu, nikoli samotný objekt.
Při volání bez nebo vymazat metody kontejneru popisovače objektů, objekty, které je zachyceno nebyla uvolněna z paměti.Musíte explicitně odstranit objekt, nebo, protože tyto objekty jsou umístěny na spravované haldě uvolňování paměti uvolnit paměť, jakmile zjistí, že objekt je již použit povolit.