Термин delete
имеет особое значение в C ++, поэтому использование удалено нежелательно.
MyObject my_object = MyObject(0);
В этой строке объявляется, что объект типа MyObject
создан с автоматической продолжительностью хранения (т. Е. В стеке). Этот объект будет уничтожен (т.е. его деструктор будет выполнен), когда закончится область действия. В Стандарте не предусмотрено никаких положений для восстановления памяти (см. Более поздний пример).
Этот объект типа MyObject
будет создан с использованием выражения MyObject(0)
. Этот конструктор инициализирует память, выделенную для исключительного использования.
Примечание: на самом деле, можно создать временный объект и затем вызвать конструктор копирования, но, к счастью, большинство компиляторов отказываются от этого промежуточного шага, как это предусмотрено стандартом.
my_object = MyObject(1);
Эта строка присваивает новое значение, определяемое выражением MyObject(1)
, уже существующему объекту my_object
. Для этого создается временный тип MyObject
с автоматической продолжительностью хранения. Затем выполняется оператор присваивания; если он не перегружен, он скопирует временное состояние в my_object
, стирая предыдущее состояние. В конце выражения временное уничтожается (опять же, не делается никаких условий для вспоминания связанной памяти).
Примечание: MyObject(0)
не «удаляется», так как он не существует, вместо этого память, в которую он записал свое состояние, используется повторно для копирования состояния из MyObject(1)
.
Как и было обещано, так как это, кажется, беспокоит вас, обсуждение аспектов памяти. Это зависит от компилятора, но большинство компиляторов ведут себя аналогично.
Предположим, что у нас есть следующая функция:
void f() {
MyObject my_object = MyObject(0);
{
my_object = MyObject(1);
do_something(my_object);
}
{
my_object = MyObject(2);
do_something(my_object);
}
}
Сколько места требуется в стеке?
- Мы предполагаем, что он выполняет прямое построение на первой строке
- Мы предполагаем, что компилятор недостаточно умен, чтобы выполнять раскраску стека (например, Clang этого не делает)
С этим допущением требуется место для 3 MyObject
.
MyObject my_object = MyObject(0);
: my_object
нужно жить до конца функции
my_object = MyObject(1);
: временная потребность должна быть создана
my_object = MyObject(2);
: временная потребность должна быть создана
Пространство стека восстанавливается в конце выполнения функции.
Если компилятор был достаточно умен, чтобы выполнять Stack Coloring, тогда два временных (которые никогда не нужны вместе) могли бы использовать одну и ту же область памяти, таким образом снижая требования к пространству до 2 MyObject
.
Интеллектуальный оптимизатор также может, возможно, напрямую встраивать MyObject(1)
и MyObject(2)
непосредственно в my_object
(если он может доказать, что эффекты будут такими же, как создание временного объекта и затем его копировать), тем самым уменьшая Требуемое пространство до 1 MyObject
.
Наконец, если определение do_something
является видимым и оно не использует свой параметр, то при определенных условиях оно может (теоретически) полностью обойти конструкцию my_object
. Такая оптимизация может быть очевидна с помощью простых программ, таких как:
int main() { int i = 0; for (; i < 1000; ++i); return i; }
, которые тривиально оптимизированы для:
int main() { return 1000; }
(обратите внимание, как исчезло i
)
Как вы можете заметить ... на самом деле очень трудно догадаться, на что способен компилятор / оптимизатор. Если у вас действительно жесткие требования к памяти, то (возможно, на удивление) лучше всего заменить блоки на функции.