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:
Platform::Collections::Vector sınıfı std::vector sınıfına benzer.
Platform::Collections::Map sınıfı std::map sınıfına benzer.
Platform::Collections::VectorView sınıfı ve Platform::Collections::MapView sınıfı ve
Map
'ninVector
salt okunur sürümleridir.Yineleyiciler Platform::Collections Ad Alanında tanımlanır. Bu yineleyiciler STL yineleyicilerinin gereksinimlerini karşılar ve herhangi bir Windows::Foundation::Collections arabirim türünde veya Platform::Collections somut türünde std::find, std::count_if ve diğer STL algoritmalarının kullanımını etkinleştirir. Örneğin, bu, C# dilinde oluşturulan bir Windows Çalışma Zamanı bileşenindeki bir koleksiyonu yineleyebileceğiniz ve buna bir STL algoritması uygulayabileceğiniz anlamına gelir.
Önemli
Ara sunucu yineleyicileri
VectorIterator
veVectorViewIterator
proxy nesneleriVectoryProxy<T>
kullanmak veArrowProxy<T>
STL kapsayıcıları ile kullanımı etkinleştirmek için. Daha fazla bilgi için bu makalenin devamında yer alan "VectorProxy öğeleri" bölümüne bakın.C++/CX koleksiyon türleri, STL kapsayıcılarının desteklediği iş parçacığı güvenliği garantisini destekler.
Windows::Foundation::Collections::IObservableVector ve Windows::Foundation::Collections::IObservableMap , koleksiyon çeşitli şekillerde değiştiğinde tetiklenen olayları tanımlar. Bu arabirimleri uygulayarak Platform ::Collections::Map ve Platform::Collections::Vector , XAML koleksiyonlarıyla veri bağlamayı destekler. Örneğin, bir koleksiyona bir öğe eklediğinizde veriye bağlı bir
Grid
öğesinizVector
varsa, değişiklik Kılavuz kullanıcı arabirimine yansıtılır.
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 IVector
değiştirerek Vector
hatayı düzeltebilirsiniz.
Önemli
Kendi programınızda bir dizi geçiriyorsanız, veya std::vector
'den IVector
daha 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^> vec
tü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
p2
aynı 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.
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 IMap
değ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::map
maliyetinden 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::DateTime
skaler 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 Map
salt 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 Vector
salt 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 Vector
için STL kullanımını basitleştirmek için begin İşlevi ve bitiş İşlevi üye olmayan işlevlerin aşırı yüklemelerini destekler. MapView
Map
VectorView
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 Vector
kullanırken Map
bunları açıkça oluşturmanız veya kullanmanız gerekmeyen türler ad alanında Details
tanımlanır.