《Effective C++》- 极精简版 21-30条

        本文章属于专栏- 概述 -《业界C++进阶建议整理》-CSDN博客


       本文列出《Effective C++》的21-30条的个人理解的极精简版本。

  • 21、在创建一个新对象时,永远不要返回引用
    • 在函数中创建对象,无论是栈上对象(会变成悬空引用),还是堆上对象(容易内存泄漏),都不要返回引用
    • 注意operator= 并不是返回一个新的对象,其是返回的自身,所以返回*this的引用
  • 22、成员变量全用private
    • protected并不比public更有封装性
    • 个人见解:对于新的程序,可以保持这样的态度。对于维护程序,有时候代码的一致性更加重要,易于维护
  • 23、用non-member、non-friend替换member函数
    • 个人见解:对于仅调用多个成员函数的函数,用non-member理论上增加了一点封装性(能访问到私用成员变量的函数越少,封装越好),但是non-member函数需要在另一个地方维护(一般用namespace维护),增加了代码阅读的难度,分散了精力
  • 24、当所有参数需要类型转换,使用non-member函数
    • 对成员函数,const A operator*(const A& a) const;如果A可以由int隐式转换,则 2*a会失败,所以必须是non-member函数const A operator*(const A& lhs, const A& rhs)
    • 个人见解:业务应用代码中,放弃2*a这种隐氏转换的逻辑,节约不了多少代码,也没有提升性能的作用。实践中,先转换,再用operator更好
  • 25、考虑写一个不抛异常的swap
    • 标准库的std::swap是异常安全的。有时候为了性能,需要一个不抛异常的。如代码
template <typename T>
void customSwap(T& a, T& b) noexcept {
    T temp = std::move(a);
    a = std::move(b);
    b = std::move(temp);
}
  • 26、尽可能延后变量定义
    • 变量的定义是需要耗费资源的,只在使用之前定义,能提高性能
    • 个人见解:c语言的习惯是在函数前几行就定义好。但性能不如使用前定义好的,除非编译器优化,但是不要寄托太多的希望在编译器优化上
  • 27、尽量少做转型动作
    • 转型动作:
      • const_cast:唯一有能力把变量从const转为non-const的转型操作符
      • dynamic_cast:唯一可能耗费巨大成本的转型动作。
        • 基类 -> 派生类,失败返回nullptr
        • 派生类 -> 基类,保证成功,和static_cast作用一样
      • reinterpret_cast:告诉编译器,对一个内存数据,换一个方式解释。(常用的唯一的用途,是对void*做算术偏移会用到,但也尽量别用)
      • static_cast:强迫隐式转换,无法将const转为non-const
    • 在c++中,对象的布局方式和它们的地址计算方式随编译器变化而变化。不要猜测对象在c++中如何布局。如Derived d; Base* b = &d; 如果是多继承,有时候b和d的地址一定不一样,单继承不一定,
    • static_cast转换后返回新的副本,在派生类的成员函数中调用基类的成员函数,如果用static_cast<D>(*this).fun(),则调用的不是this的fun,而是this的副本的fun,如果fun改变了成员函数,这个用法将出错。这时候应该用B::fun()
    • dynamic_cast实现取决于编译器,一个普遍的实现版本是比较class名称的字符串,对于一个四层单继承体系的对象,最多可能调用4次strcmp。
    • 对于大多数使用dynamic_cast的场景都可以通过虚函数避免。
    • 个人见解:如果要判断基类指针指向的派生类类型,在基类中加一个字段枚举效率更高
  • 28、避免返回handles(指针、引用、迭代器)指向对象的内部成分
    • 防止用户对其进行更改
  • 29、为“异常安全”(函数要么成功,要么是调用前的状态)而努力是值得的
    • 如有系统有一个函数没有异常安全,那系统就是非异常安全的。
    • 个人见解:并不赞同这条。实践中,放弃构建异常安全的c++程序。即使业务代码保持了这一特性,众多的三方库中也不能保证,并且降低了性能。付出收益比太低了。
  • 30、透彻了解inline的里里外外
    • 在同一个函数调用中,更容易被编译器优化
    • inline会使二进制膨胀并不是绝对的,在inline函数本体很小时,编译器产生的二进制可能比函数调用更小
    • inline是对编译器的申请,而不是命令。不过大多数编译器,在拒绝时会给出警告信息
    • inline是编译期行为
    • 个人见解:只对大量占用CPU资源的代码考虑是否inline。执行频率低的代码,是不是inline并不影响全局,把精力花到有价值的事情上。

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值