ฉันมีสิ่งนี้struct
:
struct Snapshot
{
double x;
int y;
};
ฉันต้องการx
และy
เป็น 0 พวกเขาจะเป็น 0 โดยค่าเริ่มต้นหรือฉันต้องทำ:
Snapshot s = {0,0};
มีวิธีอื่นใดอีกในการทำให้โครงสร้างเป็นศูนย์?
ฉันมีสิ่งนี้struct
:
struct Snapshot
{
double x;
int y;
};
ฉันต้องการx
และy
เป็น 0 พวกเขาจะเป็น 0 โดยค่าเริ่มต้นหรือฉันต้องทำ:
Snapshot s = {0,0};
มีวิธีอื่นใดอีกในการทำให้โครงสร้างเป็นศูนย์?
คำตอบ:
มันจะไม่เป็นโมฆะถ้าคุณไม่ได้เตรียมโครงสร้าง
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
ที่สองจะทำให้สมาชิกทุกคนเป็นศูนย์แรกที่พวกเขาออกจากค่าที่ไม่ได้ระบุ โปรดทราบว่ามันซ้ำ:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
ที่สองจะทำให้p.s.{x,y}
เป็นศูนย์ คุณไม่สามารถใช้รายการเริ่มต้นรวมเหล่านี้หากคุณมี Constructor ใน struct หากเป็นเช่นนั้นคุณจะต้องเพิ่มการทำให้เป็นจริงที่เหมาะสมกับตัวสร้างเหล่านั้น
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
จะเริ่มต้นทั้ง x และ y เป็น 0 โปรดทราบว่าคุณสามารถใช้x(), y()
เพื่อเริ่มต้นพวกเขาโดยไม่คำนึงถึงประเภทของพวกเขานั่นคือค่าเริ่มต้นแล้วและมักจะให้ค่าเริ่มต้นที่เหมาะสม (0 สำหรับ int, 0.0 สำหรับสองครั้ง ประเภทที่ผู้ใช้ประกาศ constructors, ... สิ่งนี้มีความสำคัญโดยเฉพาะอย่างยิ่งถ้า struct ของคุณเป็นแม่แบบ
Snapshot s = {};
ทำงานกับสมาชิกที่ไม่ได้เป็น POD (สำหรับการ zeroing พวกเขา) หรือไม่?
ไม่พวกเขาไม่ใช่ 0 โดยค่าเริ่มต้น วิธีที่ง่ายที่สุดเพื่อให้แน่ใจว่าค่าทั้งหมดหรือค่าเริ่มต้นเป็น 0 คือการกำหนดคอนสตรัคเตอร์
Snapshot() : x(0), y(0) {
}
วิธีนี้ช่วยให้มั่นใจได้ว่าการใช้ภาพรวมทั้งหมดจะมีค่าเริ่มต้น
โดยทั่วไปไม่มี อย่างไรก็ตามโครงสร้างประกาศเป็นขอบเขตไฟล์หรือคงที่ในฟังก์ชั่น / จะ / จะเริ่มต้นเป็น 0 (เช่นเดียวกับตัวแปรอื่น ๆ ทั้งหมดของขอบเขตเหล่านั้น):
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 คุณสามารถเขียน
Snapshot s = {};
คุณไม่ควรใช้ memset ใน C ++ memset มีข้อเสียเปรียบว่าถ้าไม่มี POD ในโครงสร้างมันจะทำลายมัน
หรือเช่นนี้
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
SomeType foo();
เป็นสิ่งปกติแม้ว่ามันจะเกิดขึ้นกับคนอื่น - ในนิยามฟังก์ชัน (ในกรณีนั้นคือฟังก์ชันfoo
ที่ส่งคืนSomeType
) ขออภัยสำหรับ necro แต่ถ้าใครอื่นสะดุดนี้ฉันคิดว่าฉันตอบ
ใน C ++ ให้ใช้ตัวสร้างแบบไม่มีอาร์กิวเมนต์ ใน C คุณไม่มีคอนสตรัคเตอร์ให้ใช้memset
วิธีแก้ปัญหาที่น่าสนใจ - initializers ที่กำหนด:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
ฉันเชื่อว่าคำตอบที่ถูกต้องคือค่าของพวกเขาไม่ได้กำหนด บ่อยครั้งที่มันถูกเตรียมใช้งานเป็น 0 เมื่อเรียกใช้รหัสการตรวจแก้จุดบกพร่องของรหัสรุ่น กรณีนี้มักจะไม่เกิดขึ้นเมื่อเรียกใช้รุ่นที่วางจำหน่าย
0
ในหน่วยความจำเหล่านั้น นี่ไม่ใช่การเริ่มต้นครั้งแรก!
เนื่องจากนี่คือ POD (โดยพื้นฐานแล้วคือโครงสร้าง C) จึงมีอันตรายเล็กน้อยในการเริ่มต้นวิธี C:
Snapshot s;
memset(&s, 0, sizeof (s));
หรือในทำนองเดียวกัน
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
ฉันจะไม่ไปไกลเท่าที่จะใช้calloc()
ในโปรแกรม C ++
ย้ายสมาชิกพ็อดไปที่คลาสพื้นฐานเพื่อย่อรายการ initializer ของคุณ:
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());
}