Общее правило, когда возвращать указатель против возвращаемого объекта? - PullRequest
0 голосов
/ 20 января 2020

Во многих примерах я вижу такой код:

SomeObject* constructObject() {
    SomeObject* obj = new SomeObject();
    return obj;
}

Но что говорит против того, чтобы делать это таким образом:

SomeObject constructObject() {
    SomeObject obj = SomeObject();
    return obj;
}

?

Что такое общее эмпирическое правило, когда возвращать объект, а когда возвращать указатель?

Редактировать: Небольшой фон:

Я переписываю средство визуализации, которое должно быть быстрым как в рендеринге, так и в обеспечении данные. Предыдущий программист хранил указатели в векторе. что-то вроде: vector<MeshModel*>. MeshModel само по себе не имеет никакого наследства. По моему мнению, было бы лучше использовать vector<MeshModel> вместо этого, так как я не буду случайно прыгать в памяти. Мой POV не так?

Ответы [ 4 ]

3 голосов
/ 20 января 2020

std::vector<MeshModel> является более простым, чем std::vector<MeshModel*>.

. Для использования в std::vector можно беспокоиться о стоимости конструкции копирования / перемещения во время перераспределений роста вектора. Если ваш SomeObject может быть перемещен дешево, то я бы go для хранения по стоимости. В противном случае при создании вектора может возникнуть компромисс между производительностью. Но, скорее всего, об этом не стоит беспокоиться.

Приносит ли это скорость при доступе к объектам, зависит от слишком многих других вещей (от всего, что влияет на кэширование, таких как размер объекта, частота доступа / шаг / предсказуемость, целевое оборудование). ... слишком много, чтобы перечислять здесь) - профиль, если вы заботитесь о производительности. Но нет необходимости использовать косвенное обращение, когда вы ничего от этого не получаете.

И, как указано в комментариях, держитесь подальше от владения необработанными указателями. std::unique_ptr<MeshModel> будет отлично работать в показанном коде.

2 голосов
/ 20 января 2020

Мой POV неверен?

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

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

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

1 голос
/ 20 января 2020

Обычно единственная причина для динамического выделения объекта и возврата его по указателю состоит в том, что вам нужно использовать полиморфизм (т.е. вы возвращаете объект, который является подклассом возвращаемого типа, объявленного в возвращаемом типе вашей функции) и вы хотите избежать обрезки объектов . Но даже тогда вы должны всегда возвращать, используя класс интеллектуального указателя (например, std::unique_ptr<BaseClass> или std::shared_ptr<BaseClass>), вместо того, чтобы возвращать необработанный указатель в стиле / C, так как возврат необработанного указателя является Рецепт для утечек памяти.

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

0 голосов
/ 20 января 2020

По моему мнению, изменение, которое вы предлагаете, "приятно иметь", что не является инженерно-обоснованным, если приложение работает сейчас. На самом деле это может быть очень распространенное изменение, затрагивающее большую часть кода. «Только потому, что вы думаете, что это воняет» не является действительной инженерной причиной для его изменения.

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

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

...