SORU
26 HAZİRAN 2009, Cuma


Kopyalama başlatma ve direkt başlatma C arasında bir fark var mı?

Ben bu fonksiyonu olduğunu varsayalım:

void my_test()
{
    A a1 = A_factory_func();
    A a2(A_factory_func());

    double b1 = 0.5;
    double b2(0.5);

    A c1;
    A c2 = A();
    A c3(A());
}

Her gruplandırma, bu ifadeler aynı mı? Yoksa başlatmaları bazı (muhtemelen) en iyi hale getirilebilen fazladan bir kopyası mı? İnsanlar iki şey söylemek gördüm. Lütfencitekanıt olarak metin. Diğer davalar da ekleyin lütfen.

CEVAP
26 HAZİRAN 2009, Cuma


A a1 = A_factory_func();
A a2(A_factory_func());

A_factory_func() döner ne bağlıdır. A - sonra aynı - kopya kurucu açık olduğunda, daha sonra ilk başarısız olacağını dışında yapıyor bir döner sanıyorum. 8.5/14 okuyun.

double b1 = 0.5;
double b2(0.5);

Bu dahili tip (bu bir sınıf türü burada anlamına gelir) çünkü o bir aynı şeyi yapıyor. 8.5/14 okuyun.

A c1;
A c2 = A();
A c3(A());

Bu aynı yapmıyor. İlk A non-POD bir ise varsayılan-başlatır ve bir POD (8.5/9 Okuma) için herhangi bir başlatma yapmıyor. İkinci kopya başlatır: Değer başlatır geçici ve c2 değer o zaman kopya (Okuma 5.2.3/2 8.5/14). Tabii ki bu açık seçik olmayan bir kopya kurucu (Okuma 8.5/14 12.3.1/3 13.3.1.3/1) gerektirir. Üçüncü bir işlevi döndüren bir işlev işaretçisi alır A A (Okuyun 8.2) döndüren bir işlevi olan bir beyanı c3 oluşturur.


Başlatmaları derinliklerine inmekDoğrudan ve Kopyalama başlatma

Birbirinin aynı ve aynı yapması gereken ise, bu iki şekli bazı durumlarda oldukça farklı. Başlatma iki formları doğrudan ve kopyalama başlatma

T t(x);
T t = x;

Her biri için bağlayabiliriz davranıştır

  • Doğrudan başlatma davranır gibi bir işlevi çağırmak için bir işlevde: işlevleri, bu durumda, kurucular T (dahil olmak üzere explicit olanlar) ve bağımsız değişken x. Aşırı yükleme çözünürlüğü En İyi eşleşen oluşturucu bulacaksınız, ve gerektiğinde herhangi bir örtük dönüştürme gerekli olacaktır.
  • Örtük dönüştürme sırası oluşturur kopya başlatma: türde bir nesne için x dönüştürmek için çalışır T. (O zaman bir kopya kurucu da ihtiyaç vardır. bu yüzden başlatıldı nesnesine nesne kopyalamak olabilir ama bu önemli değil aşağıda)

Gördüğünüz gibibaşlatma kopyalayındoğrudan başlatma tüm markalar mevcut aramak için vardır, ve . mümkün örtülü dönüşüm konusunda bir şekilde doğrudan başlatma bir parçasıdır: ^em>buna ek olarakherhangi bir örtük dönüştürme yapabilir değişken türleri eşleştirmek için ihtiyaçları, kopyalama başlatma sadece bir örtük dönüştürme sırası ayarlayabilirsiniz.

Uğraştım, 44**, "" explicit kurucular ile. bariz kullanmadan

#incluce <iostream>
struct B;
struct A { 
  operator B();
};

struct B { 
  B() { }
  B(A const&) { std::cout << "<direct> "; }
};

A::operator B() { std::cout << "<copy> "; return B(); }

int main() { 
  A a;
  B b1(a);  // 1)
  B b2 = a; // 2)
}
// output: <direct> <copy>

Nasıl ve neden çıktı bu sonucu mu işe yarar mı?

  1. Doğrudan başlatma

    İlk dönüşüm hakkında bir şey bilmiyor. Sadece bir kurucusunu çağırmak için çalışacağız. Bu durumda, aşağıdaki kurucu mevcuttur ve birtam eşleşme:

    B(A const&)
    

    Dönüşüm yok, çok az bir kullanıcı dönüşüm, kurucusunu çağırmak için gerekli (sabit nitelik dönüşüm burada da olur unutmayın) tanımlanmış. Ve bu yüzden doğrudan başlatma haber verir.

  2. Başlatma kopyalayın

    Olarak, kopya başlatma a 38 ** türü yok olduğunda, dönüşüm bir dizi inşa veya ondan türetilen şüphesiz, bu olay () yukarıdaki " dedi. Dönüştürme yapmak için yollar arayacaktır, ve aşağıdaki adayların bulacaksınız

    B(A const&)
    operator B(A&);
    

    Dönüştürme fonksiyonu yazdım nasıl dikkat: parametre türü olmayan sabit üye işlev içinde olmayan sabit olan this işaretçi türünü yansıtır. Şimdi, bağımsız değişken olarak x ile bu adaylar diyoruz. Eğer iki aday fonksiyonları her ikisi de aynı tür için bir referans kabul edilmesi, sonra gerekirse Çünkü . kazanan dönüştürme işlevi vardır: ^em>az inşsürüm kazanır (bu arada, aynı zamanda olmayan sabit nesneler için olmayan sabit üye işlev çağrıları tercih mekanizmasıdır).

    Unutmayın eğer biz değiştirmek dönüştürme fonksiyonu bir sabit üye işlev, sonra dönüşüm belirsiz (çünkü ikisine de sahip bir parametre türü A const&): Comeau derleyici reddeder düzgün, GCC kabul eder ama içinde olmayan ukala mod. -pedantic geçiş uygun belirsizlik de olsa uyarı çıkış yapar.

Bu biraz bu iki şekli farklı nasıl daha iyi hale getirmeye yardımcı olur umarım!

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • My Name Is Jeff

    My Name Is J

    26 ŞUBAT 2008
  • pilslajt

    pilslajt

    20 HAZİRAN 2008
  • SamsTech

    SamsTech

    4 NİSAN 2014