Далі, звичайно, все не зовсім точно. Візьміть його з зерном солі, коли прочитаєте :)
Ну, три речі, на які ви посилаєтесь, - це автоматична, статична та динамічна тривалість зберігання , яка має щось спільне з тим, як довго живуть об'єкти та коли вони починають життя.
Автоматична тривалість зберігання
Ви використовуєте автоматичну тривалість зберігання для короткочасних та малих даних, які потрібні лише локально в межах певного блоку:
if(some condition) {
int a[3]; // array a has automatic storage duration
fill_it(a);
print_it(a);
}
Тривалість життя закінчується, як тільки ми виходимо з блоку, і починається, як тільки об’єкт визначений. Вони є найпростішим видом тривалості зберігання та значно швидше, ніж зокрема динамічна тривалість зберігання.
Статична тривалість зберігання
Ви використовуєте статичну тривалість зберігання для вільних змінних, до яких може бути доступний будь-який код постійно, якщо їх обсяг дозволяє таке використання (область простору імен), а також для локальних змінних, які потребують продовження їхнього життя через вихід із сфери їх дії (локальна область) та для змінних членів, які повинні бути спільними для всіх об'єктів свого класу (область класів). Їх термін служби залежить від обсягу вони знаходяться. Вони можуть мати область простору імен і локальну область і область видимість класу . Те, що стосується обох, це те, що, як тільки починається їх життя, життя закінчується в кінці програми . Ось два приклади:
// 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
це відбувається, коли введено тіло функції. Для об'єктів із області імен час життя починається при запуску програми . Те саме стосується статичних об'єктів сфери дії класу:
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();
}
Термін його служби закінчується лише тоді, коли ви зателефонуєте на видалення для них. Якщо ви це забудете, ці об’єкти ніколи не закінчують життя. І об’єкти класу, які визначають конструктор, оголошений користувачем, не будуть викликати своїх деструкторів. Об'єкти, що мають динамічну тривалість зберігання, вимагають вручну обробляти їх термін експлуатації та пов'язаний з цим ресурс пам'яті. Бібліотеки існують, щоб полегшити їх використання. Явне збирання сміття для конкретних об'єктів можна встановити за допомогою інтелектуального вказівника:
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