Udostępnij za pośrednictwem


Pojemniki STL/CLR.

Biblioteki STL/CLR ma kontenery, które zostały znalezione w standardowa biblioteka języka C++, ale działa w ramach zarządzanego środowiska.NET Framework.Jeśli są znane z biblioteki szablon standardowy (STL), STL/CLR jest najlepszym sposobem nadal używać umiejętności, które już opracowane podczas uaktualniania kodu do docelowego common language runtime (CLR).

Ten dokument zawiera omówienie kontenerów w STL/CLR, takie jak wymagania dotyczące pojemnika, typów elementów, że można wstawić do pojemników i kwestie własności z elementami w pojemnikach.Gdzie stosowne, wymienione są różnice między macierzystych bibliotekę i STL/CLR.

Wymagania dotyczące elementów kontenera

Wszystkie elementy wstawione do kontenerów STL muszą przestrzegać niektórych wytycznych.Aby uzyskać więcej informacji, zobacz Wymagania dotyczące elementów kontenera STL/CLR..

Ważne elementy kontenera

Pojemniki STL/CLR mogą zawierać jedną z dwóch typów elementów:

  • Uchwyty, aby odwołać typów.

  • Typy odwołań.

  • Typy wartościach rozpakowanych.

Nie można wstawić spakowanymi typami wartości do dowolnej kontenerów STL/CLR.

Bb385236.collapse_all(pl-pl,VS.110).gifUchwyty do typy odwołań

Uchwyt do typu odwołania można wstawić do kontenera STL/CLR.Uchwyt w C++, który CLR jest analogiczne do wskaźnika w macierzystym C++.Aby uzyskać więcej informacji, zobacz Operator uchwytu do obiektu (^) (C++ Component Extensions).

Bb385236.collapse_all(pl-pl,VS.110).gifPrzykład

Poniższy przykład ilustruje sposób wstawić uchwyt do obiektu pracownika 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(pl-pl,VS.110).gifTypy odwołań

Jest również możliwe wstawienie typu odwołania (zamiast dojścia do typ odwołania) do kontenera STL/CLR.Tutaj podstawową różnicą jest to, że po usunięciu kontener typy odwołań destruktor jest wywoływana dla wszystkich elementów wewnątrz tego kontenera.W kontenerze dojścia do typy odwołań nie zostanie wywołana destruktory dla tych elementów.

Bb385236.collapse_all(pl-pl,VS.110).gifPrzykład

Poniższy przykład ilustruje sposób wstawić obiekt pracownika do 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(pl-pl,VS.110).gifTypy wartości rozpakowanych

Można także wstawić typu wartościach rozpakowanych w pojemniku STL/CLR.Typ wartościach rozpakowanych jest typ wartości, która nie została ramkach do typu odwołania.

Element typu wartości może być jednym z typów wartości standardowych, takich jak int, lub może być typu wartości zdefiniowane przez użytkownika, takie jak value class.Aby uzyskać więcej informacji zobaczKlasy i struktury (C++ Component Extensions)

Bb385236.collapse_all(pl-pl,VS.110).gifPrzykład

Poniższy przykład modyfikuje pierwszy przykład wprowadzając pracownika klasy typu wartości.Ten typ wartości zostanie wstawiony na cliext::set tak jak w pierwszym przykładzie.

// 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;
}

Jeśli próba wstawienia uchwyt na wartość typu do kontenera, C3225 błąd kompilatora jest generowany.

Bb385236.collapse_all(pl-pl,VS.110).gifWydajność i implikacje pamięci

Przy określaniu, czy za pomocą uchwytów odwołać typów lub wartość jako kontenery, należy wziąć pod uwagę kilka czynników.Jeśli użytkownik zdecyduje się użyć typy wartości, należy pamiętać, wykonywana jest kopia elementu, za każdym razem, gdy element jest wstawiany do kontenera.Dla małych obiektów nie powinno to być problem, ale jeśli obiekty są wstawiane są duże, wydajność może ponieść.Także jeśli używasz typów wartości jest niemożliwe do przechowywania jeden element w kilku pojemnikach w tym samym czasie, ponieważ każdy pojemnik musi własną kopię elementu.

Jeśli zdecydujesz się odwołać typów w zamian za pomocą uchwytów, wydajność może zostać zwiększona, ponieważ nie jest konieczne skopiować elementu, gdy dodaje się w kontenerze.Również w odróżnieniu od z typów wartości tego samego elementu może istnieć w wielu pojemników.Jednak jeśli użytkownik zdecyduje się użyć uchwytów, należy uważać, aby zapewnić, że dojście jest prawidłowy i że odnosi się do obiektu nie została usunięta gdzie indziej w taki sposób, w programie.

Kwestie własności z kontenerów

Pojemniki w STL/CLR pracować na semantykę wartości.Przy każdym Wstawianie elementu kontenera dodaje się kopię tego elementu.Jeśli chcesz pobrać semantyki podobne odniesienie, można wstawić uchwyt obiekt zamiast samego obiektu.

Podczas wywołania wyczyść lub wymazać metoda kontenera obiektów uchwyt obiektów, które można znaleźć w uchwyty nie są zwalniane z pamięci.Użytkownik musi jawnie usunięcia obiektu albo, ponieważ obiekty te znajdują się na stercie zarządzanych umożliwić garbage collector zwolnić pamięć, po Określa, że obiekt jest już używany.

Zobacz też

Informacje

Standardowa biblioteka szablonu