2012-02-19 23 views
5

Veri yapısını geçmek için bellek ayırmanın gerekli olduğu standart bir yineleyici düşünün. Standart, bellek atanamazsa yineleyicinin bir istisna atmasına izin veriyor mu? Örnek olarak, ağaç veri yapıları için bir giriş yineleyici düşünün. Bu durumda, ağacın üstesinden gelmek için, her düğümün üst öğesine bir işaretçi eklemeniz ve sürdürmeniz gerekir (bu, ağaçta ekleme/silme/bulma hakkında olduğu gibi bu tür bir işaretçiye ihtiyaç duymayan işlemleri yavaşlatır) veya bir yığın kullanır. Yineleyicinin, işaretçileri çapraz düğümlere depolamasına yardımcı olmak için. Bu durumda, yığın ilerlerken boş bellek kalmayıncaya ve yineleyici atmaya zorlanana kadar büyüyebilir.Standart yineleyici işlemlerinin atmasına izin verilir mi?

+0

"Bu durumda, ağacın üstesinden gelmek için, her düğümün üst öğesine bir işaretçi eklemeniz ve korumanız gerekir" Her düğümün * ebeveynine bir işaretçi göstermesi gerekir. Aksi halde sadece aşağı inebileceğiniz "ileri" bir ağaç. Yığını kullanan bir yineleyicinin, hem genel hem de paylaşılan bir nesneye (dolayısıyla iş parçacığı için güvenli olmayan) güvenmek ve yalnızca ağacı çaprazlamak için bellek ayırmak için kırılacağını söyleyebilirim. C++ 11'deki "std :: forward_list" için yineleyicilerin ileri yineleyiciler olduğunu unutmayın; sen hiç geri dönemezsin. –

+1

@Nicol Yığının global olacağını veya paylaşılacağını kim söyledi? Yığın yineleyici örneğiyle ilişkilendirilir. Dahası, yığınlar, düğümlerin yalnızca halefleri için işaretçilere sahip olduğu ağaçlara * giriş yineleyicileri * uygulamak için tek yoldur. – Martin

+0

Giriş yineleyicileri * veri yapısına * eleman eklemezler. Sadece var olan elemanları okuyabilir ve değiştirebilirler. Çıkış yineleyicileri yapabilir, ancak bunların çoğunun yineleme değil, * kapsayıcılar için yineleyici bağdaştırıcı olduğunu fark edersiniz. Ve ağaç düğümleri ebeveynlerine işaret etmelidir. –

cevap

5

Evet, C++ uygulamasında bir yineleyici yönteminin atmasına izin verilir ve belirttiğiniz gibi bazı durumlarda atılabilir.

C++ 'da atamayacağınız işlevlerin tek sınıfı bir yıkıcıdır. Ve gerçekten bu sadece bir sözleşmeyle (çünkü belirli işlemleri doğru yapmak neredeyse imkansız hale getirir). Destraktörler atabilir, bırakmaları için çok kötü.

Bireysel işlevler, atmalarını önlemek için throw() ile işaretlenebilir.

+0

"C + + 'da atanamayan tek işlev bir yıkıcıdır." Doğru değil. Standart, atmasına izin verilmeyen oldukça az sayıda standart kütüphane fonksiyonunu tanımlar. Örneğin, "auto_ptr" yapıcılarının çoğu C++ 03'te "throw()" olarak adlandırılırlar, yani atılamazlar. C++ 11'de hemen hemen her "swap" uygulaması "noexcept" ile tanımlanır. –

+0

@NicolBolas Bir sınıfın/işlev türünün atılmasına izin verilip verilmediğine dair genel bir açıklama yapmaya çalışıyordum. Throw() 'değiştiricisi kesinlikle bireysel bir fonksiyonun atamayacağını söylüyor. Bununla ilgili bir not ekleyeceğim. "Noexcept" ile aşina değilim, bunun için iyi bir referans sayfanız var mı? – JaredPar

+0

@JaredPar: C++ 11'de tanıtılan yeni sözdizimi. Hangi Visual C++ şimdiye kadar göz ardı edilmiş olsa da, uygulanacak en kolay şeylerden biri olması gerekir (neredeyse 'throw() '+ tipte bir özellik). C++ 11 Standardının 15.4 ve 5.3.7 bölümlerine bakınız. –

İlgili konular