Вы должны переосмыслить свои предположения, интерфейс функций должен быть определен в терминах семантики.Итак, главный вопрос: Какова семантика функции?
Если ваша функция создает объект, независимо от того, насколько большим или маленьким он является для копирования, вам следуетвозврат по значению независимо от того, как часто вызывается код.Если, с другой стороны, то, что вы делаете, - это предоставление доступа к уже существующему объекту, тогда вы должны вернуть ссылку на объект в обоих случаях.
Обратите внимание:
expensive function() {
expensive result;
return result;
}
expensive x = function();
Может быть оптимизирован компилятором в один объект expensive
(он может избежать копирования из result
в возвращаемый объект и удалить копию из возвращенного объекта в x
).
По принципу подстановки Лискова вы здесь не следуете, один тип возвращает объект, а другой возвращает ссылку на объект , которые во многих отношениях совершенно разные вещи, так что дажеесли вы можете применить похожие операции к двум возвращаемым типам, то факт, что есть другие операции, которые не совпадают, и есть разные обязанности, которые передаются вызывающей стороне.
Например, если вы изменяете возвращенный объект в ссылочном регистре, вы изменяете значение all возвращаемых объектов из функциив будущем, в то время как в случае значения объект принадлежит вызывающей стороне, и не имеет значения, что делает вызывающая сторона с его копией, следующий вызов функции вернет вновь созданный объект без этихИзменения.
Итак, еще раз, подумайте о том, что такое семантика вашей функции, и используйте ее, чтобы определить, что возвращать во всех производных классах.Если вы не уверены, насколько дорогой кусок кода, вы можете вернуться с упрощенным вариантом использования, и мы можем обсудить, как повысить производительность приложения.Для этого вам необходимо четко указать, что пользовательский код делает с объектами, которые он получает, и что он ожидает от функции.