C++. Что означает «автоматический стек»?
Вопрос
Просматривая просторы Интернета, я наткнулся на эта почта, который включает в себя это
«(Хорошо написано) 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. Ему не нужна операция копирования, чтобы его можно было использовать в качестве автоматического стека, или так ли это?