2010-05-12 13 views
20

Aşağıdaki yapı beyanına sahip olduğumu varsayalım (kurucu olmayan basit yapı). ŞimdiÜye yapı, memset çağırmadan yapıcı başlatıcı listesinden sıfır-init olabilir mi?

struct Foo 
{ 
    int x; 
    int y; 
    int z; 
    char szData[DATA_SIZE]; 
}; 

en bu yapı bir C üyesi olduğunu varsayalım ++ sınıfı aşağıdaki gibi:

class CFoobar 
{ 
    Foo _foo; 
public: 
    CFoobar(); 
}; 

şöyle ben CFoobar yapıcısını bildirirseniz:

CFoobar::CFoobar() 
{ 
    printf("_foo = {%d, %d, %d}\n", _foo.x, _foo.y,_foo.z); 
    for (int x = 0; x < 100; x++) 
     printf("%d\n", _foo.szData[x]); 
} 

beklediğiniz gibi, ne zaman CFoobar'ın kurucusu çalışıyor, çöp verisi yazdırılıyor Açıkçası, kolay düzeltme memset veya ZeroMemory & _foo'dur.

CFoobar::CFoobar() 
: _foo() 
{ 

bu sıfır çıkış üyesi görünen o: Ben şöyle eğer hiçbir parametrelerle şantiye başlatma listesine _foo eklemek fark ettiniz ... Ancak ben her zaman ne yaptığımı

var _foo değişkenleri. En azından linux üzerinde g ++ ile durum buydu.

Şimdi benim sorum: Bu standart C++ mı yoksa bu derleyici özgü bir davranıştır? standart davranış ise

biri bana resmi bir kaynaktan gelen bir başvuru alıntı yapabilirsiniz? Daha karmaşık yapıları ve sınıfları olan örtük sıfır başlangıç ​​davranışıyla ilgili herhangi bir "yakalama" var mı?

cevap

11

Evet, bu, standarda göre davranış olarak tanımlanmıştır. 12.6.2 [class.base.init]/3: "sentezleme listesi mem-başlatıcı arasında atlanırsa, temel sınıf veya üye subobject olan değer başlatıldı" Foo bir POD-tipi değildi ama yine de hiçbir kullanıcısının bildirdiği yapıcısı olsaydı

(örneğin bir std::string türü vardı) sonra bazı çok popüler derleyiciler değil doğru bunu değer başlatmak istiyorum, ama, uyarılırsınız. Bir yapıcı başlatıcısı-listesinde başlatıcısı olarak () kullandığınızda Bildiğim

Tüm derleyiciler doğru POD üyelerinin değer başlatma gerçekleştirmek yoktur.

+0

"Bazı popüler derleyiciler" = VC6 Varsayalım? Çünkü son 10 yıldaki herhangi bir derleyicide yanlış davranış görmedim. – MSalters

+0

@MSalters: Ve ne yazık ki VS2005 ve VS2008 derleyicileri. Bunu VS2010'da denemedim. –

+0

@MSalters: Yalnızca kullanıcı tarafından bildirilen kurucular olmadan POD olmayan yapı üyeleri için geçerli değildir; diğer türler düzgün çalışıyor. Connect'te bununla ilgili birkaç rapor var. Bu bulduğum bir tanesi: https://connect.microsoft.com/VisualStudio/feedback/details/484295/vc-does-not-value-initialize-members-of-derived-classes-without-user-declared-constructor –

2

i zor standardını okumak buluyorum ama sanırım buldum: T türünde bir nesne değer başlatmak

için şu anlama gelir:
T sendikasız sınıf tipi bir olmadan ise kullanıcı ilan yapıcı, daha sonra her bir statik olmayan verilerin elemanı ve T baz- sınıfı bileşen, sıfıra-başlatma nesne ve daha sonra varsayılan kurucu çağırarak uygulanabilir, örneğin, bir sınıf nesnesi için değer başlatıldı değeri başlatma olup.

Bölüm 8.5

+0

8.5, bu üye-başlatıcısının gerçekten _value-initialization_ için çağırdığını bilmek için 12.6.2 ile birlikte okunmalıdır. –

1

Bu değer gösterme tüm bit sıfır bile float foo = float();

Bu nesne sıfırlar eşdeğerdir. Yani memset()'dan bile daha iyi.

İlgili konular