SORU
17 Temmuz 2014, PERŞEMBE


Taşıma semantiği ve işlevi sipariş değerlendirme

Aşağıdaki: yoktur sanırım

#include <memory>
struct A { int x; };

class B {
  B(int x, std::unique_ptr<A> a);
};

class C : public B {
  C(std::unique_ptr<A> a) : B(a->x, std::move(a)) {}
};

Eğer "bilinmeyen sipariş işlev parametreleri" doğru, bu kodu güvenli bir yer değildir. yaklaşık C kuralları anladıysam Eğer ikinci argüman için B'nin kurucu ise inşa edilen ilk kullanarak hareket kurucu, sonra a şimdi içerir nullptr ifade a->x tetik tanımsız davranış (muhtemelen segfault). Eğer ilk değişken ilk inşa edilirse, o zaman her şeyin beklendiği gibi çalışır.

Eğer bu normal bir işlev çağrısı olsaydı, sadece bir geçici yaratabiliriz:

auto x = a->x
B b{x, std::move(a)};

Ama sınıf başlatma listesinde geçici değişkenleri oluşturmak için özgürlük yok.

B, orada yukarıdaki gerçekleştirmek için başka bir yolu değiştiremez sanırım? Ve aynı işlevi unique_ptr kaldırma hareketli bir geçici oluşturmadan ifade diyoruz yani?

Eğer Bdeğiştirmek olsaydı'nin kurucu ama setX(int) gibi yeni yöntemler eklemek değil? Bu işe yarar mı?

Teşekkür ederim

CEVAP
17 Temmuz 2014, PERŞEMBE


Liste başlatma B oluşturmak için kullanın. Öğeleri daha sonra sağdan sola doğru değerlendirilmesi için garanti edilir.

C(std::unique_ptr<A> a) : B{a->x, std::move(a)} {}
//                         ^                  ^ - braces

Dan§8.5.4/4 [malzeme.ınit.listesi]

İçindebaşlatıcı listesibirhazırladı-ınit-listesi,başlatıcı-babalarpack açılımı (14.5.3) kaynaklanan da dahil olmak üzere, göründükleri sırayla değerlendirilir. Yani, her değeri hesaplama ve belirli bir yan etkisi ile ilişkilibaşlatıcı maddeher değeri hesaplama ve herhangi bir yan etkisi ile ilgili daha önce sıralıbaşlatıcı maddebu virgülle ayrılmış listesi izlerbaşlatıcı listesi.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jay Will

    Jay Will

    19 NİSAN 2006
  • MandMEvangelists

    MandMEvangel

    28 Ocak 2008
  • Ralph Phillips

    Ralph Philli

    5 Aralık 2006