Aracılığıyla paylaş


Koleksiyonlar (C++/CX)

C++/CX programında, Standart Şablon Kitaplığı (STL) kapsayıcılarını veya başka bir kullanıcı tanımlı koleksiyon türünü ücretsiz olarak kullanabilirsiniz. Ancak, koleksiyonları Windows Çalışma Zamanı uygulama ikili arabirimi (ABI) arasında (örneğin, bir XAML denetimine veya javaScript istemcisine) geçirdiğinizde, Windows Çalışma Zamanı koleksiyon türlerini kullanmanız gerekir.

Windows Çalışma Zamanı koleksiyonlar ve ilgili türler için arabirimleri tanımlar ve C++/CX, collection.h üst bilgi dosyasındaki somut C++ uygulamalarını sağlar. Bu çizim, koleksiyon türleri arasındaki ilişkileri gösterir:

Koleksiyon türleri için C artı C X devralma ağacı diyagramı.

Vektör kullanımı

Sınıfınızın bir dizi kapsayıcısını başka bir Windows Çalışma Zamanı bileşenine geçirmesi gerektiğinde, parametre veya dönüş türü olarak Windows::Foundation::Collections:: IVector<T> ve somut uygulama olarak Platform::Collections::Vector<T> kullanın. Genel dönüş değeri veya parametresinde bir Vector tür kullanmayı denerseniz, derleyici hatası C3986 tetiklenir. hatasını olarak IVectordeğiştirerek Vector hatayı düzeltebilirsiniz.

Önemli

Kendi programınızda bir dizi geçiriyorsanız, veya std::vector 'den IVectordaha verimli oldukları için kullanınVector. Yalnızca kapsayıcıyı ABI üzerinden geçirirken kullanın IVector .

Windows Çalışma Zamanı tür sistemi pürüzlü dizi kavramını desteklemez ve bu nedenle dönüş değeri veya yöntem parametresi olarak geçiremezsinizIVector<Platform::Array<T>>. ABI'de pürüzlü bir diziyi veya dizi dizisini geçirmek için kullanın IVector<IVector<T>^>.

Vector<T> koleksiyondaki öğeleri eklemek, kaldırmak ve bunlara erişmek için gereken yöntemleri sağlar ve örtük olarak 'a IVector<T>dönüştürülebilir. Örneklerinde STL algoritmaları Vector<T>da kullanabilirsiniz. Aşağıdaki örnekte bazı temel kullanımlar gösterilmektedir. Buradaki begin işlevi ve end işlevi ad alanından değil ad alanındandır Platform::Collections std.

#include <collection.h>
#include <algorithm>
using namespace Platform;
using namespace Platform::Collections;
using namespace Windows::Foundation::Collections;


void Class1::Test()
{
    Vector<int>^ vec = ref new Vector<int>();
    vec->Append(1);
    vec->Append(2);
    vec->Append(3);
    vec->Append(4);
    vec->Append(5);


    auto it = 
        std::find(begin(vec), end(vec), 3);

    int j = *it; //j = 3
    int k = *(it + 1); //or it[1]

    // Find a specified value.
    unsigned int n;         
    bool found = vec->IndexOf(4, &n); //n = 3

    // Get the value at the specified index.
    n = vec->GetAt(4); // n = 3

    // Insert an item.
    // vec = 0, 1, 2, 3, 4, 5
    vec->InsertAt(0, 0);

    // Modify an item.
    // vec = 0, 1, 2, 12, 4, 5,
    vec->SetAt(3, 12);

    // Remove an item.
    //vec = 1, 2, 12, 4, 5 
    vec->RemoveAt(0);

    // vec = 1, 2, 12, 4
    vec->RemoveAtEnd();

    // Get a read-only view into the vector.
    IVectorView<int>^ view = vec->GetView();
}

kullanan std::vector mevcut kodunuz varsa ve bunu bir Windows Çalışma Zamanı bileşeninde yeniden kullanmak istiyorsanız, koleksiyonu ABI üzerinden geçirdiğiniz noktada oluşturmak Vector için bir std::vector veya bir çift yineleyici alan oluşturuculardan birini Vector kullanın. Aşağıdaki örnekte, bir öğesinden verimli başlatma için taşıma oluşturucusunun Vector nasıl kullanılacağı gösterilmektedir std::vector. Taşıma işleminden sonra özgün vec değişken artık geçerli olmaz.

//#include <collection.h>
//#include <vector>
//#include <utility> //for std::move
//using namespace Platform::Collections;
//using namespace Windows::Foundation::Collections;
//using namespace std;
IVector<int>^ Class1::GetInts()
{
    vector<int> vec;
    for(int i = 0; i < 10; i++)
    {
        vec.push_back(i);
    }    
    // Implicit conversion to IVector
    return ref new Vector<int>(std::move(vec));
}

Abi'nin ileriki bir noktasında geçirmeniz gereken bir dize vektörü varsa, dizeleri başlangıçta tür olarak mı yoksa tür olarak std::wstring Platform::String^ mı oluşturacağınız konusunda karar vermeniz gerekir. Dizelerde çok fazla işlem yapmanız gerekiyorsa kullanın wstring. Aksi takdirde, dizeleri tür olarak Platform::String^ oluşturun ve bunları daha sonra dönüştürme maliyetinden kaçının. Ayrıca, bu dizeleri bir std:vector içine mi yoksa Platform::Collections::Vector dahili olarak mı koyacağınız konusunda da karar vermeniz gerekir. Genel bir uygulama olarak, yalnızca kapsayıcıyı ABI'ye geçirdiğinizde kullanın std::vector ve ondan bir Platform::Vector oluşturun.

Vektördeki değer türleri

Platform::Collections::Vector içinde depolanacak tüm öğeler, örtük olarak veya sağladığınız özel bir std::equal_to karşılaştırıcı kullanılarak eşitlik karşılaştırmasını desteklemelidir. Tüm başvuru türleri ve tüm skaler türler, eşitlik karşılaştırmalarını örtük olarak destekler. Windows::Foundation::D ateTime gibi skaler olmayan değer türleri için veya özel karşılaştırmalar (örneğin, objA->UniqueID == objB->UniqueID) için özel bir işlev nesnesi sağlamanız gerekir.

VectorProxy öğeleri

Platform::Collections::VectorIterator ve Platform::Collections::VectorViewIterator, bir IVector<T> kapsayıcısı ile std::sort gibi döngülerin ve algoritmaların kullanılmasını range for sağlar. Ancak IVector öğelere C++ işaretçi başvurusu kaldırma yoluyla erişilemez; öğelere yalnızca GetAt ve SetAt yöntemleri aracılığıyla erişilebilir. Bu nedenle, bu yineleyiciler ara sunucu sınıflarını Platform::Details::VectorProxy<T> kullanır ve Platform::Details::ArrowProxy<T> Standart Kitaplığın gerektirdiği şekilde , ->ve [] işleçleri aracılığıyla *tek tek öğelere erişim sağlar. Açıkça belirtmek gerekirse, verilen IVector<Person^> vectürü *begin(vec) şeklindedir VectorProxy<Person^>. Ancak, proxy nesnesi neredeyse her zaman kodunuz için saydamdır. Bu ara sunucu nesneleri, yalnızca yineleyiciler tarafından iç kullanım için olduğundan belgelenmez, ancak mekanizmanın nasıl çalıştığını bilmek yararlıdır.

Kapsayıcılar üzerinde IVector aralık tabanlı for bir döngü kullandığınızda, yineleyici değişkeninin öğelere doğru şekilde bağlanmasını sağlamak için VectorProxy kullanınauto&&. kullanıyorsanız auto&, derleyici uyarısı C4239 tetiklenir ve VectoryProxy uyarı metninde belirtilir.

Aşağıdaki çizimde bir üzerinde bir range for döngü gösterilmektedir IVector<Person^>. Yürütmenin 64. satırdaki kesme noktasında durdurulduğuna dikkat edin. QuickWatch penceresinde yineleyici değişkeninin p aslında ve m_i üye değişkenleri olan bir VectorProxy<Person^> değişken olduğu m_v gösterilir. Ancak, bu değişkeni çağırdığınızda GetType , örneğine Person p2aynı türü döndürür. Sonuç olarak QuickWatch'ta, ArrowProxy hata ayıklayıcıda belirli derleyici hatalarında veya diğer yerlerde görünse VectorProxy de genellikle bunlar için açıkça kod oluşturmanız gerekmez.

Döngüye dayalı bir aralıkta VectorProxy hata ayıklama işleminin ekran görüntüsü.

Ara sunucu nesnesinin etrafında kod yazmanız gereken senaryolardan biri, öğeler üzerinde bir dynamic_cast gerçekleştirmeniz gereken senaryodur; örneğin, bir UIElement öğe koleksiyonunda belirli bir türdeki XAML nesnelerini ararken. Bu durumda, önce öğesini Platform::Object^ olarak atamanız ve ardından dinamik atamayı gerçekleştirmeniz gerekir:

void FindButton(UIElementCollection^ col)
{
    // Use auto&& to avoid warning C4239
    for (auto&& elem : col)
    {
        Button^ temp = dynamic_cast<Button^>(static_cast<Object^>(elem));
        if (nullptr != temp)
        {
            // Use temp...
        }
    }
}

Eşleme kullanımı

Bu örnekte, öğeleri ekleme ve Bir Platform::Collections::Map içinde arama ve ardından salt okunur bir Windows::Foundation::Collections::IMapView türü olarak döndürme Map gösterilmektedir.

//#include <collection.h>
//using namespace Platform::Collections;
//using namespace Windows::Foundation::Collections;
IMapView<String^, int>^ Class1::MapTest()
{
    Map<String^, int>^ m = ref new Map<String^, int >();
    m->Insert("Mike", 0);
    m->Insert("Dave", 1);
    m->Insert("Doug", 2);
    m->Insert("Nikki", 3);
    m->Insert("Kayley", 4);
    m->Insert("Alex", 5);
    m->Insert("Spencer", 6);

   // PC::Map does not support [] operator
   int i = m->Lookup("Doug");
   
   return m->GetView();
   
}

Genel olarak, iç harita işlevselliği için performans nedenleriyle türünü tercih edin std::map . Kapsayıcıyı ABI'ye geçirmeniz gerekiyorsa, std::map içinden bir Platform::Collections::Map oluşturup öğesini Windows::Foundation::Collections::IMap olarak döndürünMap. Genel dönüş değeri veya parametresinde bir Map tür kullanmayı denerseniz, derleyici hatası C3986 tetiklenir. hatasını olarak IMapdeğiştirerek Map hatayı düzeltebilirsiniz. Bazı durumlarda(örneğin, çok fazla sayıda arama veya ekleme gerçekleştirmiyorsanız ve koleksiyonu ABI'de sık sık geçiriyorsanız) başından itibaren kullanmak Platform::Collections::Map daha ucuz olabilir ve dönüştürme std::mapmaliyetinden kaçınabilirsiniz. Her durumda, üç türün en az performans gösterenleri olduğundan arama IMap ve ekleme işlemlerinden kaçının. IMap Yalnızca kapsayıcıyı ABI üzerinden geçirdiğiniz noktaya dönüştürün.

Eşlem'deki değer türleri

Platform::Collections::Map içindeki öğeler sıralanır. içinde depolanacak herhangi bir öğe, örtük olarak veya sağladığınız özel bir Map stl::less comparator kullanarak katı zayıf sıralamayla küçük karşılaştırmayı desteklemelidir. Skaler türler karşılaştırmayı örtük olarak destekler. gibi Windows::Foundation::DateTimeskaler olmayan değer türleri için veya özel karşılaştırmalar için (örneğin, objA->UniqueID < objB->UniqueID) özel bir karşılaştırıcı sağlamanız gerekir.

Koleksiyon türleri

Koleksiyonlar dört kategoriye ayrılır: değiştirilebilir sürümler ve sıralı koleksiyonların ve ilişkilendirilebilir koleksiyonların salt okunur sürümleri. Ayrıca C++/CX, koleksiyonlara erişimi basitleştiren üç yineleyici sınıfı sağlayarak koleksiyonları geliştirir.

Değiştirilebilir bir koleksiyonun öğeleri değiştirilebilir, ancak görünüm olarak bilinen salt okunur bir koleksiyonun öğeleri yalnızca okunabilir. Platform ::Collections::Vector veyaPlatform::Collections::VectorView koleksiyonunun öğelerine yineleyici veya koleksiyonun Vector::GetAt ve dizini kullanılarak erişilebilir. İlişkili bir koleksiyonun öğelerine, koleksiyonun Map::Lookup ve bir anahtarı kullanılarak erişilebilir.

Platform::Collections::Map sınıfı
Değiştirilebilir, ilişkilendirilebilir koleksiyon. Eşleme öğeleri anahtar-değer çiftleridir. İlişkili değerini almak için anahtar aramak ve tüm anahtar-değer çiftleri arasında yineleme yapmak desteklenir.

Map ve MapView üzerinde şablon oluşturulur <K, V, C = std::less<K>>; bu nedenle karşılaştırıcıyı özelleştirebilirsiniz. Ayrıca, Vector VectorView davranışını IndexOf()özelleştirebilmeniz için üzerinde <T, E = std::equal_to<T>> şablon oluşturulur. Bu, çoğunlukla değer yapıları ve Vector VectorView için önemlidir. Örneğin, Vector<Windows::Foundation::D ateTime> oluşturmak için, DateTime == işlecini aşırı yüklemediğinden özel bir karşılaştırıcı sağlamanız gerekir.

Platform::Collections::MapView sınıfı
bir öğesinin Mapsalt okunur sürümü.

Platform::Collections::Vector sınıfı
Değiştirilebilir bir dizi koleksiyonu. Vector<T> sabit zamanlı rastgele erişimi ve amorti edilmiş-sabit zamanlı Ekleme işlemlerini destekler...

Platform::Collections::VectorView sınıfı
bir öğesinin Vectorsalt okunur sürümü.

Platform::Collections::InputIterator sınıfı
STL giriş yineleyicisinin gereksinimlerini karşılayan bir STL yineleyicisi.

Platform::Collections::VectorIterator sınıfı
STL değiştirilebilir rastgele erişim yineleyicisinin gereksinimlerini karşılayan bir STL yineleyicisi.

Platform::Collections::VectorViewIterator sınıfı
STL rastgele erişim yineleyicisinin gereksinimlerini karşılayan bir STL const yineleyicisi.

begin() ve end() işlevleri

C++/CX, , , , ve rastgele Windows::Foundation::Collections nesneleri işlemek Vectoriçin STL kullanımını basitleştirmek için begin İşlevi ve bitiş İşlevi üye olmayan işlevlerin aşırı yüklemelerini destekler. MapViewMapVectorView

Aşağıdaki tabloda kullanılabilir yineleyiciler ve işlevler listelenmektedir.

Yineleyiciler İşlevler
Platform::Collections::VectorIterator<T>

(Dahili olarak depolar Windows::Foundation::Collections:: IVector<T> ve int.)
begin/ end(Windows::Foundation::Collections:: IVector<T>)
Platform::Collections::VectorViewIterator<T>

(Dahili olarak depolar IVectorView<T>^ ve int.)
begin/ end (IVectorView<T>^)
Platform::Collections::InputIterator<T>

(Dahili olarak depolar IIterator<T>^ ve T.)
begin/ end (IIterable<T>)
Platform::Collections::InputIterator<IKeyValuePair<K, V>^>

(Dahili olarak depolar IIterator<T>^ ve T.)
başlangıç/ ucu (IMap<K,V>.
Platform::Collections::InputIterator<IKeyValuePair<K, V>^>

(Dahili olarak depolar IIterator<T>^ ve T.)
begin/ end (Windows::Foundation::Collections::IMapView)

Koleksiyon değişikliği olayları

Vector ve Map bir koleksiyon nesnesi değiştirildiğinde veya sıfırlandığında ya da koleksiyonun herhangi bir öğesi eklendiğinde, kaldırıldığında veya değiştirildiğinde gerçekleşen olayları uygulayarak XAML koleksiyonlarında veri bağlamayı destekler. Veri bağlamayı destekleyen kendi türlerinizi yazabilirsiniz, ancak bu türlerden Map devralamazsınız veya Vector bu türler korumalıdır.

Windows::Foundation::Collections::VectorChangedEventHandler ve Windows::Foundation::Collections::MapChangedEventHandler temsilcileri, koleksiyon değişikliği olayları için olay işleyicilerinin imzalarını belirtir. Windows::Foundation::Collections::CollectionChange public enum sınıfı ve Platform::Collection::Details::MapChangedEventArgs ref Platform::Collections::Details::VectorChangedEventArgs sınıfları, olaya neyin neden olduğunu belirlemek için olay bağımsız değişkenlerini depolar. *EventArgs veya Vectorkullanırken Map bunları açıkça oluşturmanız veya kullanmanız gerekmeyen türler ad alanında Details tanımlanır.

Ayrıca bkz.

Tür Sistemi
C++/CX Dil Başvurusu
Ad Alanları Başvurusu