2011-08-24 7 views
8

C# dünyasından geldiğimde, atandığım bir C++ projesinde bellek sızıntılarını ve hatalarını tanıtmamaya çalışıyorum. Veri arabelleğinden bilgi ayrıştırmak için yapıları kullanan kod yazıyorum. Arabellekte görünen veri yapılarının sayısı çalışma zamanında değişebildiğinden, işlenen verileri depolamak için bir stl vektörü kullanılır. Ben mevcut yazılımda aşağıdaki kod bloğu karşılaştım ve çalıştığını anlamak mücadele ediyorum:STL Vektörleri İçinde Kapsamı ve Nesne Ömrünü Yönetme

MyVectorOfObjects.clear(); 
for (unsigned __int8 i = 0; i < NumberOfObjects; i++) 
{ 
    MyParserObject parserObject;    // Declaring without 'new'? 
    parserObject.Decode(buffer, offset, size); // A method on the struct. 
    MyVectorOfObjects.push_back(parserObject); // Does this keep parserObject in scope? 
} 

Sorularım özellikle şunlardır: this question göre

  1. , olur değil parserObject gitmek new anahtar sözcüğünden beri kapsam dışı her yineleme kullanılmıyor? Açıkçası bu kod çalışıyor.

  2. Bu durumda, nesneyi vector içine yerleştirmek parserObject kapsamını içeride tutuyor mu?

  3. this question'a göre, parserObject kopyalanır. Bu durumda, bunun performans sonuçları (ör. Hafıza tüketimi, bellek ayırma, vb.) Nelerdir? Ayrıca, kopyalanan parserObjects daha sonra vektörle aynı kapsamı alsın mı?

Yardımlarınız için teşekkür ederiz.

+3

Bu biraz temel C++. [İyi tanıtım C++ kitabı] (http://tinyurl.com/so-cxxbooks) almayı ve ondan öğrenmeyi öneririm.C++ ve C# arasındaki büyük bir farkın farkına varmanız gerektiği söyleniyor: C++ 'da, değişkenler arasında * değerleri * (açıkça referanslar olarak belirtilmemişse) C#' da bulunurken, çoğu değişkende * referanslar bulunur * (tabii ki saymazsınız) değer türleri. –

+0

'MyParserObject parserObject;' ile, bu bellek otomatik olarak program tarafından yönetilir - bunu uygulamada gerçekleşmesi gerekmediği halde, 'for'-loop'dan hemen sonra' delete parserObject 'olarak düşünün. –

+0

@ R.Martinho Referans ve teşekkürler için teşekkürler. – bporter

cevap

7
  1. Evet, for döngü içinde bildirilmiş parserObject örneği her seferinde kapsam dışında döngü yineler gider.

  2. Hayır, parserObject'un vector içine yerleştirilmesi, bu nesneyi kapsam dahilinde tutmaz. push_back() yöntemi, şimdi vector'a ait olan nesnenin bir kopyasını oluşturacaktır. Nesnelerinizin düzgün bir şekilde kopyalanabildiğinden emin olmanız gerekir (kopya yapıcı ve görev operatörü gerekli olabilir). Bu örnekteki vektörde yer alan kopyalar vektöre aittir ve vector'unkine benzer nesne ömürlerine sahip olacaktır.

  3. paserObject kopyalanır ve bunun bellek kullanımı ve performansı üzerinde etkileri olabilir. parserObject kopyalamak için önemsiz değilse, o zaman bu pahalı bir işlem olabilir. Bu, tümüyle parserObject uygulamanıza bağlıdır.

+0

İki iyi cevap ve keşke ikisini de kabul edebilseydim; Ancak seçim yapmak zorunda kalmak, bu soruları açıkça yanıtladı. Yardımlarınız için hepinize teşekkürler. – bporter

4
MyVectorOfObjects.push_back(parserObject); // Does this keep parserObject in scope? 

push_back nesne ve saklar bir kopyasını oluşturur. Bu nedenle, işaretçisi üye (ler) i varsa, MyParserObject sınıfı için kopya-yapıcı (ve kopya atama) tanımladığınızdan emin olun. Veya MyParserObject'un her üyesi aynı modeli takip ettiğinde (yani, kopya oluşturucu (ve kopyalama-atamasını) işaretçi üyeleri veya eşdeğeri varsayılan kodla eşleştiyse, derleyicinin oluşturduğu varsayılan kod yeterli olur derleyici tarafından oluşturulan vb sağlanan yeterli .... ve olacaktır.)

+0

Bu, kopyalanan her parserObject öğesinin MyVectorOfObjects kapsam dahilinde olduğu sürece kapsamda kalacağı anlamına mı geliyor? – bporter

+0

(@bporter). Evet .... – Nawaz

+1

C++ 0x ile çalışıyorsanız, taşıma yapıcı ve taşıma işleçlerini de tanımladığınızdan emin olun. –