Bende bu var struct
:
struct Snapshot
{
double x;
int y;
};
Ben istiyorum x
ve y
0 olmak. Varsayılan olarak 0 olacak mı ya da yapmak zorunda:
Snapshot s = {0,0};
Yapıyı sıfırlamanın diğer yolları nelerdir?
Bende bu var struct
:
struct Snapshot
{
double x;
int y;
};
Ben istiyorum x
ve y
0 olmak. Varsayılan olarak 0 olacak mı ya da yapmak zorunda:
Snapshot s = {0,0};
Yapıyı sıfırlamanın diğer yolları nelerdir?
Yanıtlar:
Yapıyı başlatmazsanız bunlar boş olmaz.
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
İkincisi tüm üyeleri sıfırlar, birincisi onları belirtilmemiş değerlerde bırakır. Yinelemeli olduğuna dikkat edin:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
İkincisi p.s.{x,y}
sıfır yapar. Yapınızda yapı oluşturucular varsa bu toplu başlatıcı listelerini kullanamazsınız. Eğer durum buysa, bu inşaatçılara uygun initalizasyon eklemeniz gerekecek
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
Hem x hem de y'yi 0'a x(), y()
başlatacaktır. Türlerini dikkate almadan başlatmak için kullanabileceğinizi unutmayın : Bu daha sonra değer başlatmadır ve genellikle uygun bir başlangıç değeri verir (int için 0, double için 0.0, kullanıcı için varsayılan yapıcı çağrılır kullanıcının yapıcı olarak bildirdiği türler, ...) Bu, özellikle yapınız bir şablonsa önemlidir.
Snapshot s = {};
POD üyesi olmayanlar için çalışacak (onları sıfırlamak için)?
Hayır, varsayılan olarak 0 değildir. Tüm değerlerin veya varsayılan 0 olarak ayarlandığından emin olmanın en basit yolu bir yapıcı tanımlamaktır
Snapshot() : x(0), y(0) {
}
Bu, tüm Anlık Görüntü kullanımlarının başlangıç değerlerine sahip olmasını sağlar.
Genel olarak, hayır. Bununla birlikte, bir işlevde dosya kapsamı veya statik olarak bildirilen bir yapı / 0 olarak başlatılır / sıfırlanır (bu kapsamların diğer tüm değişkenleri gibi):
int x; // 0
int y = 42; // 42
struct { int a, b; } foo; // 0, 0
void foo() {
struct { int a, b; } bar; // undefined
static struct { int c, d; } quux; // 0, 0
}
POD ile ayrıca yazabilirsiniz
Snapshot s = {};
Memset'i C ++ ile kullanmamalısınız, memset, yapıda POD olmayan bir varsa onu yok edecek dezavantajına sahiptir.
ya da bunun gibi:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
SomeType foo();
diğerleriyle birlikte olsa da tipik olanı - işlev tanımlarına (bu durumda foo
geri dönen bir işlev SomeType
) dönüştürür. Necro için özür dilerim, ama eğer başka biri tökezlese, cevap vereceğimi düşündüm.
C ++ 'da, bağımsız değişken yapıcıları kullanın. C'de yapıcılarınız olamaz, bu yüzden ya memset
da - ilginç çözüm - belirlenmiş başlatıcıları kullanın:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
Doğru cevabın değerlerinin tanımsız olduğuna inanıyorum. Genellikle, kodun hata ayıklama sürümlerini çalıştırırken 0 olarak başlatılırlar. Yayın sürümlerini çalıştırırken genellikle durum böyle değildir.
0
bellekte bu yerlerde var olur . Bu, başlatma ile aynı şey değildir!
Bu bir POD (esas olarak bir C yapısı) olduğundan, C yolunun başlatılmasında çok az zarar vardır:
Snapshot s;
memset(&s, 0, sizeof (s));
veya benzer şekilde
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
Şimdiye kadar calloc()
bir C ++ programında kullanmak için gitmek değildir .
Başlatıcı listenizi kısaltmak için bölme üyelerini temel sınıfa taşıyın:
struct foo_pod
{
int x;
int y;
int z;
};
struct foo : foo_pod
{
std::string name;
foo(std::string name)
: foo_pod()
, name(name)
{
}
};
int main()
{
foo f("bar");
printf("%d %d %d %s\n", f.x, f.y, f.z, f.name.c_str());
}