Я видел многочисленные аргументы, что использование возвращаемого значения предпочтительнее для параметров. Я убежден в причинах, почему их избегают, но я не уверен, сталкиваюсь ли я с ситуациями, когда это неизбежно.Как избежать параметров?
Часть первая моего вопроса: Каковы некоторые из ваших любимых/распространенных способов обойти использование параметра out? Материал в строках: Человек, в экспертных обзорах, я всегда вижу, что другие программисты делают это, когда они могли бы легко сделать это таким образом.
Часть вторая моего вопроса касается некоторых конкретных случаев, с которыми я столкнулся, когда бы хотел избежать параметра out, но не могу придумать, как это сделать.
Пример 1: У меня есть класс с дорогой копией, которую я бы хотел избежать. Работа над объектом может быть выполнена, и это создает дорогостоящий объект для копирования. Работа по созданию данных также не является тривиальной. В настоящее время я передам этот объект в функцию, которая изменит состояние объекта. Это для меня предпочтительнее вводить объект, внутренний для рабочей функции, и возвращать его обратно, поскольку он позволяет мне хранить вещи в стеке.
class ExpensiveCopy //Defines some interface I can't change.
{
public:
ExpensiveCopy(const ExpensiveCopy toCopy){ /*Ouch! This hurts.*/ };
ExpensiveCopy& operator=(const ExpensiveCopy& toCopy){/*Ouch! This hurts.*/};
void addToData(SomeData);
SomeData getData();
}
class B
{
public:
static void doWork(ExpensiveCopy& ec_out, int someParam);
//or
// Your Function Here.
}
Используя свою функцию, я получаю код вызова, как это:
const int SOME_PARAM = 5;
ExpensiveCopy toModify;
B::doWork(toModify, SOME_PARAM);
Я хотел бы иметь что-то вроде этого:
ExpensiveCopy theResult = B::doWork(SOME_PARAM);
Но я, если это не знаю возможно.
Второй пример: У меня есть массив объектов. Объекты в массиве являются сложным типом, и мне нужно выполнить работу над каждым элементом, работа, которую я хотел бы отделить от основного цикла, который обращается к каждому элементу. Код в настоящее время выглядит так:
std::vector<ComplexType> theCollection;
for(int index = 0; index < theCollection.size(); ++index)
{
doWork(theCollection[index]);
}
void doWork(ComplexType& ct_out)
{
//Do work on the individual element.
}
Любые предложения относительно того, как бороться с некоторыми из этих ситуаций? Я работаю в основном на C++, но мне интересно узнать, облегчают ли другие языки более легкую настройку. Я встречал RVO как возможное решение, но мне нужно больше узнать об этом, и это похоже на специфику компилятора.
Семантики неконстантного опорного параметра, что он будет (может) быть изменен в функции. Если бы вы не собирались менять его, вы бы передали его как ссылку на const. – Bill
* «но мне интересно узнать, облегчают ли другие языки более легкую настройку» * - такие языки, как Java и C#, просто не имеют этой проблемы, поскольку они всегда ссылаются на объекты вокруг. –
Замечательные ответы от всех. У меня было ощущение, что в моих конкретных примерах не было бы другого выбора.Я видел публикации на SO от людей, которые так категоричны относительно того, как они избегают параметров любой ценой. Я надеялся, что, может быть, один из них сможет рассказать о том, как они достигают такого подвига. Что касается RVO, я несколько не решаюсь использовать специфические функции компилятора, так как было бы трудно объяснить моим начальникам, почему мне нужно перепроектировать половину моего кода, потому что он больше не работает из-за недостающей функции в результате изменение/обновление компилятора. –