Следующее, конечно, все не совсем точно. Возьми это с крошкой соли, когда читаешь:)
Итак, три вещи, на которые вы ссылаетесь: автоматическое, статическое и динамическое время хранения , которые имеют отношение к тому, как долго живут объекты и когда они начинают жить.
Автоматическая продолжительность хранения
Вы используете автоматическую продолжительность хранения для короткоживущих и небольших данных, которые необходимы только локально в некотором блоке:
if(some condition) {
int a[3]; // array a has automatic storage duration
fill_it(a);
print_it(a);
}
Время жизни заканчивается, как только мы выходим из блока, и начинается, как только объект определен. Они являются наиболее простым видом продолжительности хранения и намного быстрее, чем, в частности, продолжительность динамического хранения.
Статическая продолжительность хранения
Вы используете статическую длительность хранения для свободных переменных, к которым может обращаться любой код в любое время, если их область допускает такое использование (область пространства имен), и для локальных переменных, которым необходимо продлить срок их службы при выходе из своей области (локальная область) ), и для переменных-членов, которые должны использоваться всеми объектами их класса (класс classs). Их время жизни зависит от области, в которой они находятся. Они могут иметь область имен и локальную область и область класса . Что верно для них обоих, так это то, что как только начинается их жизнь, время жизни заканчивается в в конце программы . Вот два примера:
// 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
привязан не к конкретным объектам своего класса, а к самому классу. Адрес всех трех имен выше одинаков, и все они обозначают один и тот же объект. Существует специальное правило о том, когда и как инициализируются статические объекты, но сейчас не будем об этом беспокоиться. Это означает термин статический порядок инициализации фиаско .
Динамическая продолжительность хранения
Последнее время хранения является динамическим. Вы используете его, если хотите, чтобы объекты жили на другом острове, и вы хотите поместить указатели вокруг них. Вы также можете использовать их, если ваши объекты большие и если вы хотите создать массивы размером, известным только в runtime . Из-за этой гибкости объекты, имеющие динамическую продолжительность хранения, являются сложными и медленными в управлении. Объекты с такой динамической длительностью начинают время жизни, когда происходит соответствующий оператор new :
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();
}
Вам не нужно заботиться о вызове delete: общий ptr сделает это за вас, если последний указатель, который ссылается на объект, выходит из области видимости. Сам общий ресурс имеет автоматическую продолжительность хранения. Таким образом, его время жизни автоматически управляется, что позволяет ему проверять, должен ли он удалять указанный динамический объект в своем деструкторе. Ссылка на shared_ptr приведена в дополнительных документах: http://www.boost.org/doc/libs/1_37_0/libs/smart_ptr/shared_ptr.htm