Учитывая новый набор инструментов, предоставляемый С++, многие программисты, стремясь упростить код, выразительность, эффективность, проскальзывать через свой старый код и сделать трюки (некоторые бессмысленные, некоторые успешные) для достижения своих целей. Не пытаясь потерять слишком много времени на таких трудах и просто сделать неинтрузивные и самодостаточные изменения, каковы лучшие практики?
Позвольте мне вычеркнуть очевидное:
-
Используйте авто для запуска циклов на основе итератора:
for (std::vector<foo>::const_iterator it(lala.begin()), ite(lala.end()); it != ite; ++it); // becomes for (auto it(lala.cbegin()), ite(lala.cend()); it != ite; ++it);
-
Используйте связь для нескольких назначений, которые просто создают строки кода C (как назначить сразу несколько значений в структуру?)
a = 1; b = 2; c = 3; d = 4; e = 5; // becomes std::tie(a, b, c, d, e) = std::make_tuple(1, 2, 3, 4, 5);
-
Чтобы сделать класс не наследуемым, просто объявите его "окончательным" и удалите код, который достиг такого поведения http://www.parashift.com/c++-faq/final-classes.html
-
Используйте ключевое слово delete, чтобы явно скрыть конструкторы/деструкторы вместо того, чтобы объявлять их приватными (например, код для создания объектов с кучей, не копируемых объектов и т.д.)
-
Поверните тривиальные функторы, созданные только для упрощения выполнения одного алгоритма STL в функциях lambda (помимо уменьшения загромождения кода у вас будут гарантированные встроенные вызовы)
-
Упростите обтекание RAII объекта с помощью умного указателя
-
Избавьтесь от bind1st, bind2nd и просто используйте bind
-
Заменить написанный вручную код для типов типов (Is_ptr_but_dont_call_for_const_ptrs < > и таких:)) со стандартным кодом, предоставленным type_traits >
-
Остановить включение форвардных заголовков для функциональности, теперь вложенных в STL (BOOST_STATIC_ASSERT vs static_assert)
-
Предоставить семантику перемещения в классы (хотя это не будет считаться грязным/быстрым/легким изменением)
-
Используйте nullptr, если это возможно, вместо макроса NULL и избавитесь от кода, который заполняет контейнеры указателей с 0, отлитыми от типа объекта
std::vector<foo*> f(23); for (std::size_t i(0); i < 23; ++i) { f[i] = static_cast<foo*>(0); } // becomes std::vector<foo*> f(23, nullptr);
-
Очистить синтаксис доступа к данным для данных
std::vector<int> vec; &vec[0]; // access data as a C-style array vec.data(); // new way of saying the above
-
Заменить throw() с помощью noexcept (кроме исключения устаревшего исключения, вы получаете некоторые преимущества по скорости http://channel9.msdn.com/Events/GoingNative/2013/An-Effective-Cpp11-14-Sampler @00.29.42)
void some_func() noexcept; // more optimization options void some_func() throw(); // fewer optimization options void some_func() ; // fewer optimization options
-
Замените код, в котором вы нажимали tempory в контейнере, и надеялись, что оптимизатор будет удален от копии, с функцией "emplace" , где это возможно, чтобы отлично переправить аргумент и построить непосредственно объект в контейнер без временных.
vecOfPoints.push_back(Point(x,y,z)); // so '03 vecOfPoints.emplace_back(x, y, z); // no copy or move operations performed
UPDATE
Ответ Шафика Яхмура был по праву награжден за щедрость за то, что он получил наибольшее признание со стороны аудитории.
Ответ R Sahu был моим принятым, потому что комбинация функций, которые он предлагает, захватывает дух рефакторинга: сделать код более понятным и чистым, более простым и элегантным.