Тест
Чтобы было интереснее, сначала небольшой тест.
1. Что такое method chaining? В суть этого приема?
2. Как он реализуется в С++?
3. Сможете ли вы придумать потенциально опасную ситуацию, связанную с импользованием этого приема?
Теория
Иногда, при использовании или написании больших классов возникает необходимость вызвать подряд несколько методов объекта этого класса. Обычно это выглядит так:
class worker { public: void set_data(const data_t& d); void process(); void send_result(); void print_log(); ... }; void foo() { worker w; w.set_data(data_t{}); w.process(); w.send_result(); w.print_log(); ... }
Прием method chaining позволяет сократить этот код. Для этого мы в каждом нашем методе возвратим ссылку на наш объект и выстроим вызовы в цепочку.
class worker { public: worker& set_data(const data_t& d){...; return *this;} worker& process(){...; return *this;} worker& send_result(){...; return *this;} worker& print_log(){...; return *this;} ... }; void foo() { worker w; w.set_data(data_t{}).process().send_result().print_log(); ... }
Насколько я знаю, такой прием любят в Java. В С++ он не пользуется особой популярностью и я ни в коем случае не призываю его использовать, но знать о нем, думаю, не помешает.
Подводный камень
Строго говоря, то что я опишу ниже относится не столько к method chaining, сколько к порядку вычисления аргументов и вызовов функций, но тем не менее при использовании “цепочки вызовов” эти правила на первый взгляд могут работать неожиданно. Итак.
struct worker { worker& process(int& i) { i = 185; return *this; } worker& print_result(const int& i) { std::cout <<"result: "<< i << std::endl; return *this; } }; int main() { int data = 0; worker w; w.process(data).print_result(data+2); }
Этот код скомпилируется без предупреждений и ошибок. Но результаты выполнения могут отличаться на разных компиляторах.
Дело в том, что хотя стандарт и гарантирует, что process() будет вызвана перед print_result(), но не гарантируется, что перед аргумент функции print_result будет вычислен после выполнения process(). Соответственно, иногда в результате выполнения этого кода может быть выведено “2”.
ссылка на оригинал статьи http://habrahabr.ru/post/215059/
Добавить комментарий