Функции возвращают большой выход по значению вместо по ссылке или указателю
Этот дефект возникает, когда функции возвращают большие выходные объекты по значению вместо объекта, возвращаемого ссылкой или указателем.
Эта проверка возникает, если оба из этих условий верны:
Адрес возвращенного объекта остается действительным после 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
. Общепринятая функция getter для такого частного объекта, как getName
, который возвращает большой объект m_names
. Потому что тип возврата getNames
задается как const std::string
вместо const std::string&
функция возвращает большой объект по значению вместо по ссылке. Дорогой возврат по копии может быть не замечено, потому что этот код компилируется и функционирует правильно, несмотря на недостающие &
. Для аналогичных источников неэффективности смотрите Expensive pass by value
и Expensive copy in a range-based for loop iteration
.Чтобы исправить этот дефект, возвращайте объекты с помощью ссылок. При использовании кода С используйте указатели, чтобы избежать возврата объектов по значению.
Чтобы вернуть объекты из функции 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++ |
По умолчанию: Off |
Синтаксис командной строки
: EXPENSIVE_RETURN_BY_VALUE |
Влияние: Средний |
Expensive copy in a range-based for loop iteration
| Expensive local variable copy
| Expensive pass by value
| Find defects (-checkers)