C++. Что означает «автоматический стек»?

StackOverflow https://stackoverflow.com/questions/30099

  •  09-06-2019
  •  | 
  •  

Вопрос

Просматривая просторы Интернета, я наткнулся на эта почта, который включает в себя это

«(Хорошо написано) C ++ идет на большую длину, чтобы создать автоматические объекты работают« так же, как «примитивы, как это отражается в советах Stroustrup», чтобы «делать, как это делают».Это требует гораздо большей приверженности принципам объектно -ориентированного развития:Ваш класс не подходит, пока он не работает как «int», следуя «правилу трех», которое гарантирует, что оно может (точно так же, как int), скопирован и правильно уничтожен как автоматический стек ».

Я немного написал код на C и C++, но мимоходом, ничего серьезного, но мне просто интересно, что именно это означает?

Может ли кто-нибудь привести пример?

Это было полезно?

Решение

Объекты стека обрабатываются компилятором автоматически.

Когда область остается, она удаляется.

{
   obj a;
} // a is destroyed here

Когда вы делаете то же самое с «новым» объектом, вы получаете утечку памяти:

{
    obj* b = new obj;
}

b не уничтожается, поэтому мы потеряли возможность вернуть память, которой владеет b.И, что еще хуже, объект не может очиститься сам.

В C распространено следующее:

{
   FILE* pF = fopen( ... );
   // ... do sth with pF
   fclose( pF );
}

В C++ мы пишем это:

{
   std::fstream f( ... );
   // do sth with f
} // here f gets auto magically destroyed and the destructor frees the file

Если мы забудем вызвать fclose в примере C, файл не закроется и не сможет использоваться другими программами.(например.его нельзя удалить).

Другой пример, демонстрирующий объектную строку, которая может быть создана, назначена и которая уничтожается при выходе из области действия.

{
   string v( "bob" );
   string k;

   v = k
   // v now contains "bob"
} // v + k are destroyed here, and any memory used by v + k is freed

Другие советы

В дополнение к другим ответам:

Язык C++ на самом деле имеет auto Ключевое слово для явного объявления класса хранения объекта.Конечно, в этом нет никакой необходимости, поскольку это подразумеваемый класс хранения локальных переменных и его нельзя нигде использовать.Противоположно auto является static (как локально, так и глобально).

Следующие два объявления эквивалентны:

int main() {
    int a;
    auto int b;
}

Поскольку это ключевое слово совершенно бесполезно, оно фактически будет переработано в следующем стандарте C++ («C++0x») и получит новое значение, а именно, оно позволит компилятору определить тип переменной на основе ее инициализации (например, var в С#):

auto a = std::max(1.0, 4.0); // `a` now has type double.

Переменные в C++ могут быть объявлены либо в стеке, либо в куче.Когда вы объявляете переменную в C++, она автоматически попадает в стек, если только вы явно не используете оператор new (он попадает в кучу).

MyObject x = MyObject(params); // onto the stack

MyObject * y = new MyObject(params); // onto the heap

Это имеет большое значение в способе управления памятью.Когда переменная объявлена ​​в стеке, она будет освобождена, когда выйдет за пределы области видимости.Переменная в куче не будет уничтожена до тех пор, пока для объекта не будет явно вызвано удаление.

Автоматические стековые переменные — это переменные, которые размещаются в стеке текущего метода.Идея создания класса, который может действовать как автоматический стек, заключается в том, что должна быть возможность полностью инициализировать его одним вызовом и уничтожить другим.Важно, чтобы деструктор освобождал все ресурсы, выделенные объектом, а его конструктор возвращал объект, который был полностью инициализирован и готов к использованию.Аналогично и с операцией копирования: класс должен иметь возможность легко создавать копии, которые являются полностью функциональными и независимыми.

Использование такого класса должно быть аналогично использованию примитивов int, float и т.д.используются.Вы определяете их (в конечном итоге присваиваете им какое-то начальное значение), а затем передаете их и, в конце концов, оставляете компилятору возможность очистки.

Поправьте меня, если я ошибаюсь, но я думаю, что операция копирования не является обязательной, чтобы в полной мере воспользоваться преимуществами автоматической очистки стека.Например, рассмотрим классический объект MutexGuard. Ему не нужна операция копирования, чтобы его можно было использовать в качестве автоматического стека, или так ли это?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top