В чем разница между созданием объекта с использованием нового и без - PullRequest
95 голосов
/ 09 сентября 2010

В C ++,

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

Time t (12, 0, 0); //t is a Time object

Time* t = new Time(12, 0, 0);//t is a pointer to a dynamically allocated Time object

Я, конечно, предполагаю, что Time (int, int, int) ctor был определен.Я также понимаю, что во втором случае нужно будет удалить t, так как он был размещен в куче.Есть ли другая разница?

Ответы [ 9 ]

118 голосов
/ 09 сентября 2010

Строка:

Time t (12, 0, 0);

... выделяет переменную типа Time в локальной области видимости, обычно в стеке, которая будет уничтожена по окончании ее области действия.

Для сравнения:

Time* t = new Time(12, 0, 0);

... выделяет блок памяти, вызывая либо ::operator new(), либо Time::operator new(), а затем вызывает Time::Time() с this, установленным вадрес в этом блоке памяти (а также возвращается как результат new), который затем сохраняется в t.Как вы знаете, обычно выполняется в куче (по умолчанию) и требует, чтобы вы delete сделали это позже в программе, в то время как указатель в t хранится , как правило, .в стеке.

28 голосов
/ 09 сентября 2010

Еще одно очевидное отличие заключается в доступе к переменным и методам t.

Time t (12, 0, 0);
t.GetTime();

Time* t = new Time(12, 0, 0);
t->GetTime();
5 голосов
/ 09 сентября 2010

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

3 голосов
/ 09 сентября 2010

Я думаю, вы уже понимаете все различия. Предполагая, что вы хорошо осведомлены о разнице в синтаксисе доступа к члену t через указатель и через переменную (ну, указатель также является переменной, но я думаю, вы понимаете, о чем я). И при условии, что вы знаете разницу между вызовом по значению и вызовом по ссылке при передаче t в функцию. И я думаю, вы также понимаете, что произойдет, если вы присваиваете t другой переменной и вносите изменения через эту другую переменную. Результат будет отличаться в зависимости от того, является ли указатель t или нет.

1 голос
/ 29 апреля 2017
  • Использовать новую: вызывать новую функцию оператора для получения динамической памяти, а затем вызывать функцию-конструктор.
  • Не использовать новую: не будет вызывать новую функцию оператора, просто напрямую вызывать функцию-конструктор,Стек будет использоваться напрямую, бесполезно для malloc.
1 голос
/ 09 сентября 2010

Нет другого различия в том, что вы уже знаете.

Предполагается, что ваш код использует службу оператора по умолчанию new.

1 голос
/ 09 сентября 2010

Нет .. Другой разницы нет ..

1 голос
/ 09 сентября 2010

Функциональная разница между объектом и его размещением в стеке отсутствует, а в куче - нет. Оба вызовут конструктор объекта.

Между прочим, я рекомендую вам использовать Boost shared_ptr или scoped_ptr, который также функционально эквивалентен при размещении в куче (с дополнительной полезностью scoped_ptr, ограничивающей вас от копирования не копируемых указателей):

scoped_ptr<Time> t(new Time(12, 0, 0));
0 голосов
/ 09 сентября 2010
void foo (Time t)
{
  t = Time(12, 0, 0);
}

void bar (Time* t)
{
  t = new Time(12, 0, 0);
}


int main(int argc, char *argv[])
{
  Time t;
  foo(t);//t is not (12,0,0),its value depends on your defined type Time's default constructor. 

  bar(&t);//t is (12,0,0)
  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...