Функции возвращают большие выходные данные по значению, а не по ссылке или указателю
Этот дефект возникает, когда функции возвращают большие выходные объекты по значению вместо объекта, возвращаемого по ссылке или указателю.
Эта проверка выполняется, если выполняются оба условия:
Адрес возвращенного объекта остается действительным после return заявление.
Возвращенный объект является одним из следующих:
Нетривиально копируемый объект. Возврат такого объекта по значению может потребовать вызова внешней функции, что дороже, чем возврат его по ссылке. Чтобы проверить, является ли объект нетривиально копируемым, используйте функцию std::is_trivially_copyable. Дополнительные сведения об этой функции см. в разделе std::is_trivially_copyable в ссылке C++.
Большой тривиально копируемый объект. Возврат тривиально копируемого объекта по стоимости дороже, когда объект большой.
Этот дефект не возникает, если возвращенный объект:
Недорого копировать.
Временный объект или нестатический локальный объект.
При возврате объекта по ссылке или указателю возвращать большой объект по значению неэффективно. Функции могут непреднамеренно возвращать большой объект по значению из-за отсутствия & или *. Такие неэффективные заявления о возврате могут быть не замечены. Рассмотрим этот код:
#include<string>
class Buffer{
public:
//..
const std::string getName() {
return m_names;
}
//...
private:
std::string m_names;
};Buffer содержит большой частный объект m_names. Для такого частного объекта обычно используется общедоступная функция получения, например, getName, который возвращает большой объект m_names. Потому что возвращаемый тип getNames устанавливается как const std::string вместо const std::string&функция возвращает большой объект по значению, а не по ссылке. Дорогой возврат копией может быть не замечен, поскольку этот код компилируется и функционирует правильно, несмотря на отсутствие &. Аналогичные источники неэффективности см. в разделе Expensive pass by value и Expensive copy in a range-based for loop iteration.Чтобы устранить этот дефект, верните объекты с помощью ссылок. При использовании кода C используйте указатели, чтобы избежать возврата объектов по значению.
Чтобы вернуть объекты из функции C++ по ссылке, задайте возвращаемый тип функции в качестве ссылки. Например:
#include<string>
class Buffer{
public:
//..
const std::string& getName() {
return m_name;
}
//...
private:
std::string m_name;
};getName() возвращает большой объект m_names по ссылке, поскольку возвращаемый тип функции const std::string&, что является ссылкой. Можно также использовать указатели, чтобы избежать возврата объектов по значению. Например, задайте возвращаемый тип getName() кому const std::string*, а затем вернуть адрес m_names как &m_names.
#include<string>
class Buffer{
public:
//..
const std::string* getName() {
return &m_name;
}
//...
private:
std::string m_name;
};getName() избегает возврата m_names по значению. Этот метод полезен в коде C, где ссылки недоступны.Повышение производительности может зависеть от используемого компилятора, реализации библиотеки и среды.
| Группа: Производительность |
| Язык: C | C++ |
| По умолчанию: Откл. |
Синтаксис командной строки:
EXPENSIVE_RETURN_BY_VALUE |
| Воздействие: среднее |
Expensive copy in a range-based for loop iteration | Expensive local variable copy | Expensive pass by value | Find defects (-checkers)