【发布时间】:2014-02-26 04:54:24
【问题描述】:
鉴于 c++ 提供的新工具集,许多程序员以代码简化、表达性、效率为目标,浏览他们的旧代码并进行调整(有些毫无意义,有些成功)以实现他们的目标。虽然尽量不要在此类工作上浪费太多时间,而只是进行非侵入性和自包含的更改,但最佳实践是什么?
让我划掉明显的:
-
使用 auto 运行基于迭代器的循环:
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); -
将 tie 用于仅生成 C 样式代码行的多个赋值 (how to assign multiple values into a struct at once?)
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); 要使类不可继承,只需将其声明为“final”并删除实现这种行为的代码http://www.parashift.com/c++-faq/final-classes.html
使用 delete 关键字显式隐藏构造函数/析构函数,而不是将它们声明为私有(例如创建基于堆的对象、不可复制对象等的代码)
-
将仅为简化单个 STL 算法的执行而创建的普通函子转换为 lambda 函数(除了减少代码混乱之外,您还可以保证内联调用)
李> 仅使用智能指针
来简化对象的 RAII 包装
摆脱 bind1st、bind2nd 并只使用 bind
用
提供的标准代码替换类型特征的手写代码(Is_ptr_but_dont_call_for_const_ptrs 等 :))
停止在 STL(BOOST_STATIC_ASSERT 与 static_assert)中包含用于功能的提升标头(BOOST_STATIC_ASSERT 与 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 -
替换您将临时推送到容器中的代码,并希望优化器将副本删除,在可用的情况下使用 "emplace" 函数,以便完美地转发参数并直接将对象构造到容器中,完全没有临时性。
vecOfPoints.push_back(Point(x,y,z)); // so '03 vecOfPoints.emplace_back(x, y, z); // no copy or move operations performed
更新
The answer by Shafik Yaghmour 理所当然地获得了观众最大的接受度。
The answer by R Sahu 是我接受的一个,因为它提出的组合 功能捕获了spirit of refactoring:使代码更清晰、更简洁、更简单、更优雅。
【问题讨论】:
-
请不要关闭这个。真的很有用。
-
我不明白这是如何“主要基于意见的”。完全没有。然而,这是这些大列表类型的问题之一,也并不真正适合 Stack Overflow 格式。
-
使用
.data()代替&container[0]有一个问题。如果您想修改内部数据,它不适用于std::string。为什么因为.data()forstd::string与.c_str()相同,并返回一个常量指针。同样对于 MSVC2013,push_back采用T&&,与emplace_back相同。 -
使用
override表示函数覆盖基类中的虚函数,而不是在基类中引入新的/隐藏函数。此外,我建议不要让每一堂课都成为决赛。应该谨慎使用它,因为它会使测试代码变得比实际更痛苦。
标签: c++ c++11 refactoring