ฉันได้พบพฤติกรรมแปลก ๆ บางอย่าง (บนเสียงดังกราวและ GCC) ในสถานการณ์ต่อไปนี้ ฉันมีเวกเตอร์ที่มีองค์ประกอบหนึ่งซึ่งเป็นตัวอย่างของการเรียนnodes
Node
จากนั้นฉันเรียกฟังก์ชันnodes[0]
ที่เพิ่มNode
เวกเตอร์ใหม่ เมื่อเพิ่มโหนดใหม่ฟิลด์ของวัตถุที่เรียกจะถูกรีเซ็ต! อย่างไรก็ตามพวกเขาดูเหมือนจะกลับสู่ปกติอีกครั้งเมื่อฟังก์ชั่นเสร็จสิ้น
ฉันเชื่อว่านี่เป็นตัวอย่างที่ทำซ้ำได้น้อยที่สุด:
#include <iostream>
#include <vector>
using namespace std;
struct Node;
vector<Node> nodes;
struct Node{
int X;
void set(){
X = 3;
cout << "Before, X = " << X << endl;
nodes.push_back(Node());
cout << "After, X = " << X << endl;
}
};
int main() {
nodes = vector<Node>();
nodes.push_back(Node());
nodes[0].set();
cout << "Finally, X = " << nodes[0].X << endl;
}
ซึ่งเอาท์พุท
Before, X = 3
After, X = 0
Finally, X = 3
แม้ว่าคุณจะคาดหวังว่า X จะยังคงไม่เปลี่ยนแปลงตามกระบวนการ
สิ่งอื่น ๆ ที่ฉันได้ลอง:
- หากฉันลบบรรทัดที่เพิ่ม
Node
ข้างในset()
ออกมามันจะส่งสัญญาณ X = 3 ทุกครั้ง - ถ้าฉันสร้างใหม่
Node
และเรียกมันว่า (Node p = nodes[0]
) แล้วเอาท์พุทคือ 3, 3, 3 - ถ้าฉันสร้างการอ้างอิง
Node
และเรียกมันว่า (Node &p = nodes[0]
) แล้วเอาท์พุทคือ 3, 0, 0 (บางทีอันนี้อาจเป็นเพราะการอ้างอิงจะหายไปเมื่อเวกเตอร์มีการปรับขนาด?)
นี่คือพฤติกรรมที่ไม่ได้กำหนดด้วยเหตุผลบางอย่าง? ทำไม?
reserve(2)
บนเวกเตอร์ก่อนที่จะเรียกset()
สิ่งนี้จะเป็นพฤติกรรมที่กำหนดไว้ แต่การเขียนฟังก์ชั่นแบบset
ที่ต้องการให้ผู้ใช้reserve
มีขนาดที่เหมาะสมอย่างเพียงพอก่อนที่จะโทรออกเพื่อหลีกเลี่ยงพฤติกรรมที่ไม่ได้กำหนดเป็นการออกแบบที่ไม่ดีดังนั้นอย่าทำ