Udostępnij za pośrednictwem


Kontenery STL/CLR

Biblioteki STL/CLR ma sam kontenery, które zostały znalezione w standardowa biblioteka języka C++, ale działa w zarządzanym środowisku.NET Framework.Jeśli są już zaznajomieni z standardowy szablon biblioteki (STL), STL/CLR jest najlepszym sposobem, aby nadal korzystać z umiejętności, które został już utworzony podczas uaktualniania kodu do obiektu docelowego common language runtime (CLR).

Ten dokument zawiera omówienie pojemników w STL/CLR, takie jak wymagania dotyczące elementów kontenera, rodzaje elementów, że można wstawiać do kontenerów i własność problemów z elementami w pojemnikach.W przypadku gdy jest to właściwe, wymienione są różnice między rodzimych standardowa biblioteka szablonów i STL/CLR.

Wymagania dotyczące elementów kontenera

Wszystkie elementy wstawione do kontenerów STL należy przestrzegać pewnych wytycznych.Aby uzyskać dodatkowe informacje, zobacz Wymagania dotyczące elementów kontenera STL/CLR.

Elementy prawidłowego kontenera

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

  • Uchwyty do typy odwołań.

  • Typy odwołań.

  • Typy wartości bez opakowania.

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

Uchwyty do typów referencyjnych

Dojście do typu odwołania można wstawić w pojemniku STL/CLR.Uchwyt w języku C++, że cele CLR jest analogiczne do wskaźnika w macierzystym C++.Aby uzyskać dodatkowe informacje, zobacz ^ (Uchwyt do obiektu na zarządzanego stosu).

Przykład

Poniższy przykład pokazuje, jak wstawić dojście 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;
}

Typy odwołań

Jest również możliwe wstawienie typu odwołania (zamiast dojścia do typu odwołania) do kontenera STL/CLR.Główną różnicą jest, że po usunięciu kontener typy odwołań destruktor Nazywa dla wszystkich elementów wewnątrz danego kontenera.W kontenerze dojścia do typów odwołań nie będzie nazywany destruktory dla tych elementów.

Przykład

Poniższy przykład pokazuje, jak 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;
}

Wartościach rozpakowanych

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

Wartość elementu typu może być jednym z typów wartości standardowych, takich jak int, lub może być typ wartości zdefiniowane przez użytkownika, takie jak value class.Aby uzyskać więcej informacji, zobacz Klasy i strukturach (zarządzanych).

Przykład

Poniższy przykład modyfikuje pierwszy przykład dokonując pracownika klasy typu wartości.Ten typ wartości zostanie wstawiony na cliext::set po prostu 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 użytkownik spróbuje wstawić dojścia do typu wartości do pojemnika, Błąd kompilatora C3225 jest generowany.

Wydajność i implikacje pamięci

Przy określaniu, czy należy odwoływać się do typu lub typów wartości jako kontenery za pomocą uchwytów, należy wziąć pod uwagę kilka czynników.Jeśli użytkownik zdecyduje się użyć typów wartości, należy pamiętać, że kopia elementu jest nawiązywane za każdym razem, gdy element jest wstawiany do kontenera.Dla małych obiektów nie powinno to być problem, ale jeśli obiekty wstawiany są duże, wydajność może ponieść.Ponadto jeśli używasz typów wartości to 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ę typy odwołań w zamian za pomocą uchwytów, ponieważ nie jest konieczne skopiować elementu po włożeniu go w kontenerze może zwiększyć wydajność.Ponadto w przeciwieństwie do 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 dbać, aby zapewnić dojście jest prawidłowy i że obiekt, który odwołuje się do nie usunięto gdzie indziej w programie.

Kwestii własnościowych z kontenerami

Kontenery w STL/CLR pracować nad semantykę wartości.Za każdym razem, wstawić element do pojemnika, kopię tego elementu zostanie wstawiony.Jeśli chcesz pobrać semantyki jak odniesienia, można wstawić dojścia do obiektu, a nie samego obiektu.

Gdy wywołanie jasne lub wymazać metoda kontenera obiektów uchwyt, obiektów, które dotyczą uchwyty nie są zwalniane z pamięci.Musisz jawnie usunąć obiekt, lub, ponieważ obiekty te znajdują się na stercie zarządzanych pozwalają moduł garbage collector zwolnić pamięć, gdy określa, czy obiekt jest już używana.

Zobacz też

Informacje

Standardowa biblioteka szablonów