共用方式為


STL/CLR 容器

STL/CLR 程式庫有標準的 C++ 程式庫中找到的同一個容器,但受管理的環境中執行。NET Framework。如果您已經熟悉使用標準樣板程式庫 (STL),STL/CLR 會繼續使用您已經發展到目標通用語言執行階段 (CLR) 升級您的程式碼時使用的技術的最佳方式。

本文件提供在 STL/CLR 容器,例如容器項目,您可以在容器中,插入,且擁有權與容器中的項目會發出的項目類型的需求的概觀。在適當的地方所提及的原生的標準樣板程式庫和 STL/CLR 之間的差異。

容器項目的需求

所有的項目插入至 STL 容器必須遵循某些規定。如需詳細資訊,請參閱 STL/CLR 容器項目的需求

有效容器項目

STL/CLR 容器可保存兩種類型的項目之一:

  • 若要參考的型別會處理。

  • 參考型別。

  • 封裝的數值型別。

您無法插入 boxed 實值型別的任何 STL/CLR 容器。

Bb385236.collapse_all(zh-tw,VS.110).gif參考型別控制代碼

您可以插入 STL/CLR 容器的參考型別控制代碼。以 CLR 為目標的 C++ 中的控制代碼是類似於原生 C++ 中的指標。如需詳細資訊,請參閱 物件控制代碼運算子 (^) (C++ 元件擴充功能)

Bb385236.collapse_all(zh-tw,VS.110).gif範例

下列範例顯示如何插入到員工物件的控制代碼 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(zh-tw,VS.110).gif參考型別

您也可插入 STL/CLR 容器中的參考型別 (而不是參考型別控制代碼)。最主要的差異是參考型別的容器刪除時,該容器內的所有項目的呼叫解構函式。在容器中的參考型別控制代碼,就不會呼叫解構函式,這些元素。

Bb385236.collapse_all(zh-tw,VS.110).gif範例

下列範例顯示如何插入員工物件到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(zh-tw,VS.110).gifUnboxed 的數值型別

您也可以插入的數值型別 STL/CLR 容器。數值型別是實值型別尚未盤成參考型別。

值的型別項目可為任一標準的實值型別,例如int,也可以是使用者定義的實值型別,例如value class。如需詳細資訊,請參閱類別和結構 (C++ 元件擴充功能)

Bb385236.collapse_all(zh-tw,VS.110).gif範例

下列範例會修改第一個範例,讓員工類別實值型別。此實值型別接著會插入cliext::set只是第一個範例所示。

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

如果您嘗試使用實值型別控制代碼中插入一種容器, 編譯器錯誤 C3225 ,就會產生。

Bb385236.collapse_all(zh-tw,VS.110).gif效能和記憶體的含意

決定是否要使用控點來參考型別或實值型別做為容器項目時,您必須考量許多因素。如果您決定要使用實值型別,請記住要在每次項目插入至容器,做一份項目。小型物件,這應該不是問題,但如果要插入的物件很大,可能會降低效能。此外,如果您正在使用實值型別,就無法儲存一個項目在多個容器中,同時因為每一個容器中會有它自己的項目複本。

如果您決定使用控點,而是參考型別,因為它不是必要時它會插入容器中建立項目的複本,就可能會提高效能。此外,與不同的是實值型別,使用相同的項目可以存在於多個容器。不過,如果您決定使用控點,您必須格外謹慎以確保控制代碼無效,而且它所參考的物件尚未刪除其他位置的程式中。

容器的擁有權問題

STL/clr 容器處理實值語意。每當您將項目插入容器時,會分別插入該項目的複本。如果您想要取得參考類似的語意時,您可以插入一個物件,而不是物件本身的控制代碼。

當您呼叫清除,或清除一個容器的控制代碼物件的方法時,控點,請參閱物件未被釋放的記憶體。您必須明確地刪除物件,或者,因為這些物件是在 managed 堆積,可讓記憶體回收行程釋放記憶體之後,它會判斷無法再使用該物件。

請參閱

參考

標準樣板程式庫