2014-07-05 27 views
8

aşağıdaki kod parçasını düşünün:Nesneden taşınan neden yıkıcı çalıştırılır?

struct foo { 
    std::string id; 
}; 

int main() { 
    std::vector<foo> v; 

    { 
    foo tmp; 
    v.push_back(std::move(tmp)); 
    } 
} 

LIVE DEMO

kod parçasının içinde ortaya:

sınıfa foo gidiyor varsayılan yapıcı nesnenin yapımı için çağırılacak
  1. tmp.
  2. foo sınıfındaki taşıma kurucusu v.push_back(std::move(tmp)); numaralı ifadede çağrılacaktır.
  3. class foo'un yıkıcısı iki kez çalıştırılacak.

Sorular:

  1. nesneden taşınmış bir yıkıcı iki kez denir ki?
  2. Gerçekten taşınmakta olan nesneden ne hareket ediyor?
+2

Taşınan nesne yalnızca bir kez bozulur. Her nesne bir kez yaratılır ve bir kez tahrip edilir. İki yıkıcı çağrı, "tmp" ve vektördeki nesne içindir. –

cevap

2

Taşınmış bir nesnenin yıkıcısı neden iki kez çağrılır?

ilk yıkıcı tahrip taşındı-dan tmp o main() ilk } de kapsam dışına çıktığında. İkinci yıkıcı tahrip hareket inşa v kapsam dışında gittiğinde push_back 'main() sonunda v içine d foo.

Gerçekten taşınmakta olan nesneden ne hareket ediyor?

bir std::string olan derleyici tarafından oluşturulan hareket yapıcı hareket-yapılar id. std::string numaralı bir hareket ettirici, genellikle, gerçek dizeyi saklayan taşınan nesnedeki bellek bloğunun sahipliğini alır ve taşınan nesneyi geçerli ancak belirtilmemiş bir duruma ayarlar (uygulamada, muhtemelen boş bir dize).

+0

"bu taşınan geçirildikten sonra, tmp yok": Eh, kapsam dışına sayesinde yok edildi ('}' push_back sonra), bu taşındı değil hemen sonra (';' push_back sonra). Bu, push_back' ile '}' arasında daha fazla kod varsa önemlidir. Oradan taşınan tmp' 'arasında rahat bir bağlantı olduğunu ve bu anlamına amaçlanmamakla edildi –

+0

@AndreKostur 'tahrip tmp'; Bu, OP'nin demosundaki ilk yıkıcı çıktısının neden boş bir dize yazdırdığını ve yıkımı sırasında 'tmp' durumunu açıkladığını açıklamayı amaçladı. Görüyorum ki, kafa karıştırıcı olabilir, bu yüzden açıklığa kavuşturuldu. –

İlgili konular