Каков наилучший способ написать функцию, которая возвращает объект в C ++?

Возможный дубликат:
как «вернуть объект» в C ++

Привет ребята!

Если мне нужно вернуть объект из функции (и он не является геттером, а также эта функция по какой-то причине не может быть реализована как конструктор, например, существует конструктор с такой же сигнатурой и различной семантикой), как лучше реализовать этот?

Например, можно предложить следующие варианты:

1) Вернуть сам объект:

MyClass GetMyClass() {
MyClass a;
...
return a;
}

В большинстве случаев RVO, http://en.wikipedia.org/wiki/Return_value_optimization выполняется, конструкторы копирования не вызываются и нет служебных данных.
Недостаток этого подхода заключается в том, что, несмотря на RVO, вы должны указать автора копирования MyClass, но, как указано в Руководстве по стилю Google C ++ …

Неявное копирование объектов в C ++ является богатым источником ошибок и проблем с производительностью.

2) Вернуть указатель на объект:

MyClass* GetMyClass() {
MyClass* a= new MyClass();
...
return a;
}

В этом случае возникают накладные расходы из-за выделения памяти в куче. Это как-то тормозит программу из-за системного вызова malloc.
Кроме того, вы должны освободить память вне этой функции, что означает, что выделение и освобождение выполняются в разных логических единицах. Как уже упоминалось здесь, Почему плохая память в функции и ее освобождение снаружи — плохая идея? это чаще всего плохая идея.

3) Передать значение по ссылке или по указателю:

void GetMyClass(MyClass& a) {
...
}

В этом случае код становится уродливым и плохо читаемым

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

5

Решение

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

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

Один из способов помочь решить проблемы со свободными указателями — использовать станд :: shared_ptr. Таким образом, вам не нужно беспокоиться об освобождении объекта, если вы всегда используете его с помощью умного указателя.

4

Другие решения

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

Там, где нет ни перемещения, ни копирования, я бы вернул указатель. Конечно, я не вернул бы голый указатель, но std::unique_ptr<T> (или же std::auto_ptr<T> (где недоступно): использование интеллектуального указателя позволяет избежать риска утечки памяти, но выбор более легкого указателя, а не, например, std::shared_ptr<T>, не принимает окончательное политическое решение о том, как объект поддерживается. В тех случаях, когда объект должен быть освобожден каким-то забавным способом, он может иметь функцию удаления.

2

По вопросам рекламы [email protected]