แน่นอนว่าทั้งหมดต่อไปนี้ไม่ค่อยแม่นยำ นำติดตัวไปด้วยเม็ดเกลือเมื่อคุณอ่าน :)
ดีสามสิ่งที่คุณอ้างถึงคือระยะเวลาการจัดเก็บอัตโนมัติแบบคงที่และแบบไดนามิกซึ่งมีบางอย่างเกี่ยวกับระยะเวลาของวัตถุที่อยู่และเมื่อพวกเขาเริ่มชีวิต
ระยะเวลาการจัดเก็บอัตโนมัติ
คุณใช้ระยะเวลาเก็บข้อมูลอัตโนมัติสำหรับข้อมูลอายุสั้นและข้อมูลขนาดเล็กซึ่งจำเป็นเฉพาะภายในเครื่องเท่านั้น:
if(some condition) {
int a[3]; // array a has automatic storage duration
fill_it(a);
print_it(a);
}
อายุการใช้งานจะสิ้นสุดลงทันทีที่เราออกจากบล็อกและจะเริ่มทันทีที่วัตถุถูกกำหนด เป็นระยะเวลาในการเก็บข้อมูลที่ง่ายที่สุดและเร็วกว่าในช่วงเวลาการจัดเก็บแบบไดนามิกโดยเฉพาะ
ระยะเวลาการจัดเก็บแบบคงที่
คุณใช้ระยะเวลาเก็บข้อมูลแบบคงที่สำหรับตัวแปรอิสระซึ่งอาจเข้าถึงได้โดยรหัสใด ๆ ทุกครั้งหากขอบเขตอนุญาตให้ใช้งานดังกล่าว (ขอบเขตเนมสเปซ) และสำหรับตัวแปรท้องถิ่นที่ต้องการยืดอายุการใช้งานตลอดช่วงเวลาที่ออกจากขอบเขต สำหรับตัวแปรสมาชิกที่ต้องใช้ร่วมกันโดยวัตถุทั้งหมดของคลาส (ขอบเขตคลาส) ชีวิตของพวกเขาขึ้นอยู่กับขอบเขตที่พวกเขาอยู่ใน. พวกเขาสามารถมีขอบเขต namespaceและขอบเขตในท้องถิ่นและขอบเขตของคลาส สิ่งที่เป็นจริงเกี่ยวกับพวกเขาทั้งสองคือเมื่อชีวิตของพวกเขาเริ่มต้นชีวิตของปลายที่สิ้นสุดของโปรแกรม นี่คือสองตัวอย่าง:
// static storage duration. in global namespace scope
string globalA;
int main() {
foo();
foo();
}
void foo() {
// static storage duration. in local scope
static string localA;
localA += "ab"
cout << localA;
}
โปรแกรมจะพิมพ์ababab
เนื่องจากlocalA
ไม่ถูกทำลายเมื่อออกจากบล็อก คุณสามารถพูดได้ว่าวัตถุที่มีขอบเขตในท้องถิ่นเริ่มต้นอายุการใช้งานเมื่อการควบคุมถึงความหมายของพวกเขา สำหรับlocalA
มันเกิดขึ้นเมื่อเข้าสู่ร่างกายของฟังก์ชั่น สำหรับวัตถุที่อยู่ในขอบเขต namespace อายุการใช้งานเริ่มต้นที่เริ่มต้นโปรแกรม เช่นเดียวกับวัตถุคงที่ของขอบเขตคลาส:
class A {
static string classScopeA;
};
string A::classScopeA;
A a, b; &a.classScopeA == &b.classScopeA == &A::classScopeA;
อย่างที่คุณเห็นclassScopeA
ไม่มีการผูกกับวัตถุเฉพาะของคลาส แต่เป็นคลาสเอง ที่อยู่ของทั้งสามชื่อด้านบนนั้นเหมือนกันและทั้งหมดแสดงถึงวัตถุเดียวกัน มีกฎพิเศษเกี่ยวกับเวลาและวิธีที่วัตถุสแตติกถูกเตรียมใช้งาน แต่ตอนนี้เราไม่ต้องกังวล นั่นคือความหมายโดยระยะคงที่เพื่อเริ่มต้นล้มเหลว
ระยะเวลาการจัดเก็บแบบไดนามิก
ระยะเวลาเก็บข้อมูลล่าสุดเป็นแบบไดนามิก คุณใช้มันหากคุณต้องการให้วัตถุอยู่บนเกาะอื่นและคุณต้องการวางพอยน์เตอร์ไว้รอบ ๆ วัตถุนั้น นอกจากนี้คุณยังใช้พวกเขาหากวัตถุของคุณมีขนาดใหญ่และถ้าคุณต้องการที่จะสร้างอาร์เรย์ขนาดเท่านั้นที่รู้จักกันที่รันไทม์ เนื่องจากความยืดหยุ่นนี้วัตถุที่มีระยะเวลาเก็บข้อมูลแบบไดนามิกจึงมีความซับซ้อนและช้าในการจัดการ วัตถุที่มีช่วงเวลาแบบไดนามิกนั้นจะเริ่มต้นอายุการใช้งานเมื่อมีการร้องขอโอเปอเรเตอร์ใหม่ที่เหมาะสมเกิดขึ้น:
int main() {
// the object that s points to has dynamic storage
// duration
string *s = new string;
// pass a pointer pointing to the object around.
// the object itself isn't touched
foo(s);
delete s;
}
void foo(string *s) {
cout << s->size();
}
อายุการใช้งานจะสิ้นสุดลงเมื่อคุณโทรลบเท่านั้น หากคุณลืมสิ่งนั้นวัตถุเหล่านั้นจะไม่มีวันจบลง และคลาสอ็อบเจ็กต์ที่กำหนดผู้ใช้ที่ประกาศตัวสร้างจะไม่มี destructors ที่เรียกว่า วัตถุที่มีระยะเวลาเก็บข้อมูลแบบไดนามิกต้องจัดการด้วยตนเองตลอดชีวิตและทรัพยากรหน่วยความจำที่เกี่ยวข้อง มีห้องสมุดเพื่อความสะดวกในการใช้งาน การรวบรวมขยะอย่างชัดเจนสำหรับวัตถุเฉพาะสามารถสร้างขึ้นได้โดยใช้ตัวชี้อัจฉริยะ:
int main() {
shared_ptr<string> s(new string);
foo(s);
}
void foo(shared_ptr<string> s) {
cout << s->size();
}
คุณไม่ต้องกังวลเกี่ยวกับการโทรลบ: ptr ที่ใช้ร่วมกันทำเพื่อคุณหากตัวชี้สุดท้ายที่อ้างอิงวัตถุนั้นอยู่นอกขอบเขต PTR ที่ใช้ร่วมกันของตัวเองมีระยะเวลาการจัดเก็บอัตโนมัติ ดังนั้นของอายุการใช้งานที่มีการจัดการโดยอัตโนมัติซึ่งจะช่วยให้ตรวจสอบว่าควรลบชี้ไปยังวัตถุแบบไดนามิกในเตาเผาของ สำหรับการอ้างอิง shared_ptr ดูที่เอกสารเพิ่ม: http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/shared_ptr.htm