2009-09-05 28 views
12

STL konteynerlerinin (vektör, liste, harita ...) değerlerini nasıl sakladığı konusunda her zaman biraz kafam karışmış durumdayım. Gönderdiğim değerlere referanslar mı depolarlar, veya kurguları kopyalayıp/kopyalar mı yoksa değerleri kendileri mi saklarlar? Örneğin STL: Referansları veya değerleri depolar?

,

int i; 
vector<int> vec; 
vec.push_back(i); 
// does &(vec[0]) == &i; 

ve

class abc; 
abc inst; 
vector<abc> vec; 
vec.push_back(inst); 
// does &(vec[0]) == &inst; 

Teşekkür

+5

Bana cevabını test edecek çalışma kodu gibi görünen bir şey var (yorumu yapmak için şartlı bir değişiklik yapmadan küçük bir değişiklikle). Koş ve gör! Oldukça eminim ki kopyaları kurup saklarlar. –

cevap

18

STL Konteynerleri kopya-yapı içeri geçmek ve mağaza değerlerini. Eğer bir kap nesneleri saklamak istiyorsanız kopyalama olmadan, kapsayıcıdaki nesneye bir işaretçi saklamayı öneririm:

class abc; 
abc inst; 
vector<abc *> vec; 
vec.push_back(&inst); 

Bu, yığın yığın çerçevelerindeki değişkenlere yapılan başvuruların yanlışlıkla saklanmasını önlemek için kap sınıflarını uygulamanın en mantıklı yoludur. Düşünün:

class Widget { 
public: 
    void AddToVector(int i) { 
     v.push_back(i); 
    } 
private: 
    vector<int> v; 
}; 

bunu tanımlandığı bir yöntemle döndükten sonra yerel bir değişkenin bellek konumunu referans olacak gibi tehlikeli olurdu i bir başvuru saklanması.

+5

C++ 'da referansları saklayan oluşturma kapsayıcıları oluşturamazsınız. Konteynere iletilen tip argümanı atanabilir olmalıdır. Referanslar atanamaz, bir nesne ile başlatılırlar ancak yapımdan sonra farklı bir nesneyi referans gösteremezler. Böylece referans tipleri, kapların içinde kullanılacak tip gereksinimlerini karşılamamaktadır. Aynı semantiklere sahip olmak istiyorsanız (veya aldıkları kadar yakınsa) bir referans sargısını (boost :: ref/boost :: cref) belirtmelisiniz –

+3

@dribeas: Bu cevap, varsayımsal riskleri açıklayarak _why not_'i açıklar. uygulanması. – MSalters

4

Bu, türünüze bağlı olarak değişir. Basit bir değer türü ve kopyalanması ucuzsa, değerlerin saklanması muhtemelen cevaptır. Öte yandan, bir referans türü veya kopyalanması pahalıysa, bir akıllı işaretçiyi (auto_ptr değil) saklayın, çünkü özel kopya semantikleri kapsayıcısında saklanmasını engeller. Paylaşılan_ptr için). Düz bir işaretçi ile bellek sızıntısı ve serbest belleğe erişim riskini kaybedersiniz. Akıllı bir işaretçi her ikisini de engeller.

+2

+1, bellekle uğraşmak için kapsayıcıların içindeki akıllı işaretçilerin kullanımına ilişkin. Başka bir seçenek, kaynak tahsisatı –

+5

ile ilgilenmek için Boost Pointer Container gibi bir kütüphane kullanıyor olabilir. OP'nin sorduğu şey bu değil. Konteynır sınıflarının konteynere yerleştirildiği zaman değeri kopyalayıp kopyalamayacağını bilmek istiyor. Cevap şu ki, evet, öyle yapıyorlar - bu nedenle söz konusu türün kopyalanması pahalıysa, işaretçilerin saklanması iyi olabilir. –

+2

Ve ne yaptığını biliyor ve kendinden sonra temizlersen çıplak işaretçiler saklamak gayet iyi. –