Создание объектов C++

Я заметил, что существует два способа создать объекты C++:

BTree *btree = new BTree;

и

BTree btree;

Из того, что я могу сказать, единственная разница находится в том, как к объектам класса получают доступ (. по сравнению с-> оператор), и когда первый путь используется, частные целые числа инициализируются к 0.

Какой путь лучше, и каково различие?

Как Вы знаете, когда использовать один или другой?

14
задан neuromancer 2 May 2010 в 00:52
поделиться

6 ответов

Два отличия:

  • они создают объекты в разных частях памяти (куча против стека)

  • время жизни объекта разное: {{ 1}} В первом случае код явно управляет выделением памяти, , а также должен управлять освобождением явно (с помощью delete / delete []).

    Во втором случае объект автоматически освобождается в конце окружающей его области видимости (метод, вложенный блок в методе или класс).

Какой из них вы используете, в основном зависит от времени жизни объекта объект (должен ли он пережить метод, в котором он создан, или нет).

32
ответ дан 1 December 2019 в 06:35
поделиться

Первая форма создает объект на куче, а вторая - на стеке.

Вторая форма будет уничтожена после завершения работы функции. Первый будет жить до тех пор, пока не будет специально удален.

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

Если объект должен пережить функцию, новая форма - лучший вариант.

5
ответ дан 1 December 2019 в 06:35
поделиться

Еще одно различие между этими двумя формами - время, когда выделяется память для этих объектов. Форма BTree bTree; называет статическое выделение, распределение которого выполняется во время компиляции, то есть компилятор размещает пространство памяти для этого объекта в памяти во время работы. В то время как выделение для BTree * pbTree = new BTree , предполагаемое динамическое выделение выполняется во время выполнения, то есть память будет выделена только тогда, когда запущенная программа достигнет этой точки.

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

// in this function, we want to return a copy of the parameter array
int *array_cpy( int *arr, int num ){
    int *copy = new int[ num ];

    int i;
    for( i = 0; i < num; i++ ){
        copy[ i ] = arr[ i ];
    }

    return copy;
}

Здесь определение int copy [num]; не подходит, одна причина связана с тем, что я сказал выше, другая - время жизни copy , пережившего функцию.Однако, учитывая, что VLA разрешен в недавней спецификации языка, вторая причина является ключевой для этой проблемы.

3
ответ дан 1 December 2019 в 06:35
поделиться

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

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

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

Срок службы памяти: Память, выделенная в куче, доступна за пределами функции распределения. Стек нет. Следуя рассуждениям о настройке указателя стека выше, после освобождения памяти она становится свободной и, скорее всего, будет перезаписана для следующего выделения стека.

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

3
ответ дан 1 December 2019 в 06:35
поделиться

Ну, они хранятся в совершенно разных областях памяти.

Вот хорошая статья. Куча и стек

0
ответ дан 1 December 2019 в 06:35
поделиться

Высокоуровневым отличием является время жизни объекта. Например, если бы вы писали видеоигру, вы бы выделили объекты, соответствующие монстрам, в куче, через new. Таким образом, базовый объект монстра живет ровно столько, сколько живет сам монстр, что неизвестно, когда вы пишете программу. Когда игрок убьет монстра, ваш код может уничтожить объект монстра с помощью delete.

Счетчик общего количества очков, с другой стороны, вы бы использовали другую форму, потому что вы знаете, как долго вы хотите, чтобы счетчик оставался на месте (предположительно, до тех пор, пока игра запущена!). Поместив эту форму в "глобальную область видимости", вне тела любой функции, она будет выделена статически, как часть бинарного файла программы.

Наконец, если вы вычисляете сумму массива, например, так:

int mysum(int* arr, int len) {
  int sum = 0;
  for (int i = 0; i < len; ++i) { sum += arr[i] }
  return sum;
}

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

2
ответ дан 1 December 2019 в 06:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: