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 sıralı kapsayıcıyı başka bir Windows Çalışma Zamanı bileşenine iletmesi gerektiğinde, Windows::Foundation::Collections::IVector<T> parametre veya dönüş türü olarak ve Platform::Collections::Vector<T> somut uygulama olarak kullanın. Genel dönüş değeri veya parametresinde bir Vector tür kullanmayı denerseniz, derleyici hatası C3986 tetiklenir. hatasını olarak Vectordeğiştirerek IVector hatayı düzeltebilirsiniz.

Important

Kendi programınızda bir dizi geçiriyorsanız, veya Vector 'den std::vectordaha verimli oldukları için kullanınIVector. 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şlev ve end işlevPlatform::Collections ad alanından, std ad alanından değil.

#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::wstringPlatform::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

içinde Platform::Collections::Vector depolanacak tüm öğeler, örtük olarak veya sağladığınız özel std::equal_to bir 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. 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 işlev nesnesi sağlamanız gerekir.

VectorProxy öğeleri

Platform::Collections::VectorIterator ve Platform::Collections::VectorViewIterator, bir range for kapsayıcı ile std::sort döngüleri ve IVector<T> gibi algoritmaların kullanılmasını 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, Standart Kitaplığın gerektirdiği şekilde Platform::Details::VectorProxy<T> ve Platform::Details::ArrowProxy<T> ara sunucu sınıflarını kullanır ve *, ->, 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 for aralık tabanlı IVector bir döngü kullandığınızda, yineleyici değişkeninin öğelere doğru şekilde bağlanmasını sağlamak için auto&& kullanınVectorProxy. kullanıyorsanız auto&, derleyici uyarısı C4239 tetiklenir ve VectorProxy 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 VectorProxy<Person^> üye değişkenleri olan bir m_v değişken olduğu m_i gösterilir. Ancak, bu değişkeni çağırdığınızda GetType , örneğine Personp2aynı türü döndürür. Sonuç olarak QuickWatch'taVectorProxyveya diğer yerlerde görünse ArrowProxy 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 Platform::Collections::Map içinde ekleme ve arama ve ardından Map'yi salt okunur bir Windows::Foundation::Collections::IMapView türü olarak döndürme 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 üzerinden geçirmeniz gerekiyorsa, Platform::Collections::Map ve std::map'den bir Map oluşturun ve Windows::Foundation::Collections::IMap olarak geri döndürün. Genel dönüş değeri veya parametresinde bir Map tür kullanmayı denerseniz, derleyici hatası C3986 tetiklenir. hatasını olarak Mapdeğiştirerek IMap 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

içindeki Platform::Collections::Map öğeler sıralanır. içinde depolanacak herhangi bir Map öğe, örtük olarak veya sağladığınız özel std::less bir karşılaştırıcı kullanarak katı zayıf sıralama ile 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. Bir Platform::Collections::Vector veya Platform::Collections::VectorView koleksiyonunun öğelerine yineleyici veya koleksiyonun Vector::GetAt ve dizini kullanılarak erişilebilir. İlişkili bir koleksiyonun öğelerine koleksiyonun Map::Lookup ve 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, VectorVectorView davranışını <T, E = std::equal_to<T>>özelleştirebilmeniz için üzerinde IndexOf() şablon oluşturulur. Bu, çoğunlukla değer yapıları ve VectorVectorView için önemlidir. Örneğin, bir Vector<Windows::Foundation::DateTime> oluşturmak için özel bir karşılaştırıcı sağlamanız gerekir çünkü DateTime == işleciyi aşırı yüklemez.

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 amortize edilmiş sabit zamanlı Append işlemleri 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, STL'nin Vector, VectorView, Map, MapView ve rastgele Windows::Foundation::Collections nesneleri işlemekte kullanımını basitleştirmek için, üye olmayan işlevlerin begin İşlev ve end İşlev aşırı yüklemelerini destekler.

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

Iterators Functions
Platform::Collections::VectorIterator<T>

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

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

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

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

(Dahili olarak IIterator<T> ve T^ depolar.)
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. Genel Windows::Foundation::Collections::CollectionChange sabit listesi sınıfı ve Platform::Collections::Details::MapChangedEventArgs ve Platform::Collections::Details::VectorChangedEventArgs ref sınıfları, olaya neyin neden olduğunu belirlemek için olay bağımsız değişkenlerini depolar. *EventArgs veya Detailskullanırken Map bunları açıkça oluşturmanız veya kullanmanız gerekmeyen türler ad alanında Vector tanımlanır.

Ayrıca bakınız

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