Saya punya ini struct
:
struct Snapshot
{
double x;
int y;
};
Saya ingin x
dan y
menjadi 0. Apakah mereka menjadi 0 secara default atau harus saya lakukan:
Snapshot s = {0,0};
Apa cara lain untuk menghilangkan struktur?
Saya punya ini struct
:
struct Snapshot
{
double x;
int y;
};
Saya ingin x
dan y
menjadi 0. Apakah mereka menjadi 0 secara default atau harus saya lakukan:
Snapshot s = {0,0};
Apa cara lain untuk menghilangkan struktur?
Jawaban:
Mereka bukan nol jika Anda tidak menginisialisasi struct.
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
Yang kedua akan membuat semua anggota nol, yang pertama meninggalkan mereka pada nilai yang tidak ditentukan. Perhatikan bahwa ini bersifat rekursif:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
Yang kedua akan menghasilkan p.s.{x,y}
nol. Anda tidak dapat menggunakan daftar penginisialisasi agregat ini jika Anda memiliki konstruktor di struct Anda. Jika demikian, Anda harus menambahkan inisialisasi yang tepat ke konstruktor tersebut
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
Akan menginisialisasi x dan y ke 0. Perhatikan bahwa Anda dapat menggunakan x(), y()
untuk menginisialisasi mereka tanpa menghiraukan tipe mereka: Itu kemudian menginisialisasi nilai, dan biasanya menghasilkan nilai awal yang tepat (0 untuk int, 0,0 untuk dua kali lipat, memanggil konstruktor default untuk ditentukan pengguna tipe yang memiliki konstruktor yang dinyatakan pengguna, ...). Ini penting terutama jika struct Anda adalah templat.
Snapshot s = {};
bekerja untuk anggota non POD (untuk mem-zeroing mereka)?
Tidak, mereka bukan 0 secara default. Cara paling sederhana untuk memastikan bahwa semua nilai atau default ke 0 adalah dengan mendefinisikan konstruktor
Snapshot() : x(0), y(0) {
}
Ini memastikan bahwa semua penggunaan Snapshot akan memiliki nilai yang diinisialisasi.
Secara umum, tidak. Namun, struct dinyatakan sebagai file-scope atau static dalam suatu fungsi / akan / diinisialisasi ke 0 (seperti semua variabel lain dari cakupan itu):
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
}
Dengan POD Anda juga dapat menulis
Snapshot s = {};
Anda tidak harus menggunakan memset di C ++, memset memiliki kelemahan bahwa jika ada non-POD dalam struct itu akan menghancurkannya.
atau seperti ini:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
SomeType foo();
adalah yang khas, meskipun dapat terjadi dengan yang lain - menjadi definisi fungsi (dalam hal ini, fungsi foo
yang mengembalikan SomeType
). Maaf untuk necro, tetapi jika orang lain menemukan ini, kupikir aku akan menjawab.
Di C ++, gunakan konstruktor tanpa argumen. Di C Anda tidak dapat memiliki konstruktor, jadi gunakan salah satu memset
atau - solusi menarik - inisialisasi yang ditunjuk:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
Saya percaya jawaban yang benar adalah bahwa nilainya tidak terdefinisi. Seringkali, mereka diinisialisasi ke 0 ketika menjalankan versi debug kode. Ini biasanya tidak terjadi ketika menjalankan versi rilis.
0
di tempat-tempat di memori. Ini tidak sama dengan inisialisasi!
Karena ini adalah POD (dasarnya sebuah C struct) ada sedikit bahaya dalam menginisialisasi dengan cara C:
Snapshot s;
memset(&s, 0, sizeof (s));
atau serupa
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
Saya tidak akan pergi sejauh yang digunakan calloc()
dalam program C ++.
Pindahkan anggota pod ke kelas dasar untuk mempersingkat daftar penginisialisasi Anda:
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());
}