Sdílet prostřednictvím


Kontejnery STL/CLR

Knihovna STL/CLR má stejné kontejnerů, které se nacházejí v Standard C++ Library, ale je spouštěn spravované prostředí.NET Framework.Pokud jste již obeznámeni s standardní šablonu knihovny (STL), STL/CLR je nejlepší způsob, jak používat dovedností, které jste již vytvořili při inovaci kódu k cíli společného jazykového modulu runtime (CLR).

Tento dokument obsahuje přehled kontejnerů v STL/CLR, jako jsou požadavky pro prvky kontejneru, typy prvků, můžete vložit do kontejnerů a vlastnictví problémy s prvky v kontejnerech.Případně jsou uvedeny rozdíly mezi nativní standardní šablonu knihovny a STL/CLR.

Požadavky pro prvky kontejneru

Všechny prvky, které jsou vloženy do STL kontejnerů musí dodržovat určité zásady.Další informace naleznete v tématu Požadavky pro prvky kontejneru STL/CLR.

Platné prvky kontejneru

STL/CLR kontejnery mohou obsahovat jednu ze dvou typů prvků:

  • Zpracovává referenční typy.

  • Typy odkazů.

  • Typy Variant hodnotu.

Typy krabici hodnot nelze vložit do libovolné kontejnery STL/CLR.

Bb385236.collapse_all(cs-cz,VS.110).gifÚchyty na typy odkazů

Popisovač typu odkazu můžete vložit do kontejneru STL/CLR.Popisovač v jazyce C++, který se zaměřuje na CLR je analogická ukazatel v nativním jazyce C++.Další informace naleznete v tématu Operátor popisovače objektu (^) (rozšíření komponent C++).

Bb385236.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad ukazuje, jak vložit popisovač 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;
}

Bb385236.collapse_all(cs-cz,VS.110).gifOdkazové typy

Je také možné vložit do STL/CLR kontejner typ odkazu (nikoli popisovač typu odkazu).Hlavní rozdíl je, že při odstranění kontejner typy odkazů se objekt se nazývá pro všechny prvky uvnitř kontejneru.V kontejneru úchyty na typy odkazů destruktory pro tyto prvky by neměla být volána.

Bb385236.collapse_all(cs-cz,VS.110).gifPří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;
}

Bb385236.collapse_all(cs-cz,VS.110).gifTypy Variant hodnoty

Typu Variant hodnotu můžete také vložit do kontejneru STL/CLR.Typ hodnoty, která nebyla je typu Variant hodnotu boxed do typu odkazu.

Typ prvku hodnota může být jeden z typů standardní hodnotu jako int, nebo může být hodnota definovaná uživatelem typu, například value class.Další informace získáte v tématu Třídy a struktury (rozšíření komponent C++)

Bb385236.collapse_all(cs-cz,VS.110).gifPříklad

Následující příklad změní první příklad tím, že hodnota typ třídy zaměstnance.Tento typ hodnoty potom vložena 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 kontejneru, C3225 chyba kompilátoru je generována.

Bb385236.collapse_all(cs-cz,VS.110).gifVýkon a důsledky paměti

Při určování, zda odkaz typy nebo typy hodnot jako prvky kontejneru pomocí táhel, je třeba zvážit několik faktorů.Pokud se rozhodnete použít typy hodnot, nezapomeňte provedení kopii prvku při každém prvku je vložen do kontejneru.Malé objekty to by neměl být problém, ale pokud rozsáhlé objekty vložen, může utrpět výkon.Také že používáte hodnoty typů je nemožné uložit jeden prvek v nádobách více současně, protože každé nádobě by měla vlastní kopii prvku.

Pokud se rozhodnete použít úchyty odkazuje typů může zvýšit výkon protože není nutné při vložení v kontejneru, vytvořte kopii prvku.Také na rozdíl od hodnoty typů téhož prvku může existovat v více kontejnerů.Však rozhodnete použít úchyty je pečlivě popisovač je platná a že objekt, který odkazuje na nebyla odstraněna jinde v programu.

Vlastnictví problémy s kontejnery

Kontejnery v STL/CLR pracovat na hodnotu sémantiku.Při každém vložení prvku do kontejneru je vložena kopie daného prvku.Pokud chcete získat sémantiku jako odkaz, můžete vložit popisovač objektu místo samotného objektu.

Při volání vymazání nebo mazání metoda kontejneru objektů popisovačů objektů popisovačů odkazujících na nebyla uvolněna z paměti.Musíte explicitně objekt odstranit, nebo, protože tyto objekty jsou umístěny ve spravovaných haldách povolit garbage collector uvolnit paměť, jakmile zjistí, že objekt je již používán.

Viz také

Referenční dokumentace

Standardní šablona knihovny