Разница между std::vector push_back(Object()) и push_back(new Object())?

В моем текущем коде я хочу вставить новые DrawObjects в созданный мной вектор,

std::vector‹ DrawObject > объекты;

В чем разница между:

objects.push_back(DrawObject(name, surfaceFile, xPos, yPos, willMoveVar, animationNumber));

а также

objects.push_back(new DrawObject(name, surfaceFile, xPos, yPos, willMoveVar, animationNumber));

person GigaBass    schedule 05.01.2013    source источник
comment
Один компилируется, другой нет.   -  person chris    schedule 05.01.2013
comment
В качестве альтернативы, с этой настройкой, один больше Java/C#, а другой - C++.   -  person chris    schedule 05.01.2013
comment
Я не вижу разумного способа компилировать их обоих... Является ли DrawObject просто классом? Это convertible_/_constructible из указателей?   -  person K-ballo    schedule 05.01.2013


Ответы (4)


Первый добавляет объект не-указатель, а второй добавляет указатель к вектору. Так что все зависит от объявления вектора, какой из них вы должны сделать.

В вашем случае, поскольку вы объявили objects как std::vector<DrawObject>, первый будет работать, так как objects может хранить элементы типа DrawObject, а не DrawObject*.

В С++ 11 вы можете использовать emplace_back как:

objects.emplace_back(name, surfaceFile, xPos, yPos, 
                     willMoveVar, animationNumber);

Обратите внимание на разницу. Сравните это с:

objects.push_back(DrawObject(name, surfaceFile, xPos, yPos, 
                            willMoveVar, animationNumber));

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

Прочитайте документ об emplace_back, в котором говорится (выделить мое),

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

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

person Nawaz    schedule 05.01.2013
comment
Хороший маленький ярлык: есть ли разница, кроме синтаксиса? Например, производительность или что-то в этом роде. - person GigaBass; 05.01.2013
comment
@ user1896797: Да, это может улучшить производительность, поскольку позволяет избежать копирования и даже перемещения. - person Nawaz; 05.01.2013

Данный

std::vector< DrawObject > objects;

Разница между двумя версиями в том, что первая верна, а вторая нет.

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

person NPE    schedule 05.01.2013

Вторая версия ожидает, что objects будет вектором указателей на DrawObject, а первая ожидает, что objects будет содержать сами объекты. Таким образом, в зависимости от объявления objects будет скомпилирована только одна из версий.

Если вы объявите objects так, как вы это сделали, будет скомпилирована только первая версия, если вы объявите объекты как std::vector< DrawObject*> objects;, будет скомпилирована только вторая версия.

person Ivaylo Strandjev    schedule 05.01.2013

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

Когда вы создаете объект без ключевого слова new, он размещается в стеке, и вы получаете доступ к этому объекту на месте.

person Caesar    schedule 05.01.2013
comment
ИМХО, это приводит к большому количеству нерелевантных деталей реализации. - person ; 05.01.2013
comment
@delnan Невежество — это блаженство. - person Caesar; 05.01.2013
comment
На самом деле это не отвечает на вопрос полностью. - person Nawaz; 05.01.2013
comment
Это помогло мне понять, что я могу создавать объекты в стеке или куче, но не применяла эту логику к созданию объектов. Может ли у меня возникнуть проблема, поскольку объект размещается в стеке? Когда он истечет в этих условиях? Это долгоживущий объект - person GigaBass; 05.01.2013
comment
@user1896797 user1896797 Жизнь объекта в стеке находится в пределах его области действия (это скобки {}, которым он принадлежит), в куче он будет жить до тех пор, пока вы не удалите его с помощью ключевого слова удаления. - person Caesar; 05.01.2013