文章目录

  • Effective C++
    • 1、类/结构体
    • 2、资源管理
    • 3、实现
    • 4、模板与泛型编程
    • 5、定制new和delete
    • 6、其他

Effective C++

1、类/结构体

1把C++看成一门独立的语言,并不是C语言的扩展。C++高效编程视情况而定,取决于你使用C++的哪一部分
2,对于单纯的常量,最好用以const对象或者enums替换#defines。
const int pi=3.14;**
2.1 对于行驶函数的宏定义,最好改为inline函数替换#defines
宏定义一个函数
#defines MAX(a,b) f((a)>(b)?(a):(b))
Ps:直接把函数变成inline函数,
3.尽可能使用const
将某些东西声明为const可以帮助编译器侦测出错误用法,const可以被施加于任何作用域对象、函数参数、函数返回类型、成员函数体。
编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”。
当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可以避免代码重复。

Class TextBlock
{Public:
Const char& operator[](std::size_t position) const
{Return text[position];
}
char& operator[](std::size_t position)
{//去除const
Return const_cast<char&>(
//为*this 加上const
static_cast<const TextBlock&>*this)[position] ;
}
}

4.编译器可以暗自为class创建default构造函数,copy构造函数,copy assignment(赋值)操作符,以及析构函数。
5.若不想使用编译器自动生成的函数,就该明确拒绝。
2种方式,1,把这些函数自己写,然后设置成private
2,函数后面写=delete(C++新特性)。

Class Test{Test()=delete;
}

6.为多态基类声明virtual函数
如果class带有任何virtual函数,他就应该拥有一个virtual析构函数。
Classes的设计目的如果不是作为base class使用,或不是为了具备多态性,就不该声明virtual析构函数。
7.别让异常逃离析构函数
析构函数绝对不要吐出异常,如果一个被析构函数调用的函数可能抛出异常,析构函数应该可以捕捉任何异常,然后吞下它们或结束程序。
如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数执行该操作。

8.绝不在构造函数和析构过程中调用virtual函数
因为这类调用从不下降至derive class

9.令operator =返回一个reference to *this(返回引用)

10.复制对象时勿忘其每一个成分
Copying函数应该确保复制“对象内的所有成员变量”及“所有base class成分”
不要尝试以某个copying函数实现另一个copying函数。应该将共同机能放进第三个函数中,并由两个copying函数共同调用。

11.让接口容易被正确使用,不易被误用

  • 好的接口很容易被正确使用,不容易被误用,你应该在你的所有接口中努力达成这些性质。
    “促进正确使用”的方法包括接口的一致性,以及内置类型的行为兼容。
    “阻止误用”的方法包括建立新类型,限制类型上的操作,束缚对象值以及消除客户的资源管理责任。
    Shared_ptr支持定制型删除器。这可防范DLL问题,可被用来自动解除互斥锁等等。

12.宁用引用传递替换值传递

  • 引用传递通常比较高效,并可避免切割问题。(内置类型,STL的迭代器,函数对象除外)

13.必须返回对象时,别妄想返回其引用

  • 绝不要返回pointer或引用指向一个局部变量(比如在函数里面创建的临时变量)或返回引用指向一个heap-allocated对象。

14.将成员函数声明为private
15.宁以non-member,non-friend替换member函数

  • 这样做可以增加封装性,包裹弹性和机能扩充性

16.若所有参数都需要类型转换,请为此采用non-member函数
17.考虑写出一个不抛出异常的swap函数,

  • 当std::swap()对你的类型效率不高时,提供一个swap函数,并确定这个函数,不抛出异常。
  • 如果你提供一个member swap,也该提供一个non-member swap用来调用前者。对于class,也请特化std::swap
  • 调用swap时应针对std::swap使用using声明式,然后调用swap并且不带任何命名空间资格修饰
  • 为用户定义类型进行std templates全特化是好的,但千万不要尝试在std内加入某些对std而言全新的东西。

18.避免遮掩继承而来的名称

  • 派生类内的名称会遮挡基类内的名称。在public继承下从来没有人希望如此。
  • 为了让被遮挡的名称再见天日,可使用using声明式或转交函数。

19.区分接口继承和实现继承

  • 接口继承和实现继承不同。在public继承下,派生类总是继承基类的接口
  • Pure virtual函数只具体指定接口继承。
  • 简朴的impure virtual函数具体指定接口继承及缺省实现继承。
  • Non-virtual函数具体指定接口继承以及强制性实现继承。

20.考虑虚函数以外的其他选择
21.绝不重新定义继承而来的non-virtual函数
22.绝不重新定义继承而来的缺省参数值。
23.明智而谨慎的使用private继承。
24.明智而谨慎的使用多继承。

2、资源管理

1.以对象管理资源

  • 为防止资源泄露,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放函数。
  • 智能指针经常被使用

2.在资源管理类中小心copy行为

  • 使用智能指针,可以避免。

3.在资源管理类中提供对原始资源的访问
- APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理之资源”的方法

 - 对原始资源的访问可能经由显式转换或隐式转换。一般而言显式转换比较安全,但隐式转换对客户比较方便。

4.成对使用new和delete时要采取相同形式

  • 因为这2个东西都是成对出现的,采用相同的形式,才可以正确匹配成功,否则会匹配出错,导致出现错误或者出现资源泄露。

5.以独立语句将newed对象置入智能指针

  • 以独立语句将newed对象存储于智能指针中。如果不那么做,一旦异常被抛出,有可能导致难以察觉的资源泄露。
Std::tr1::shared_ptr<T>pw(new T);
Function(pw,....);
//先创建一个对象,防止函数出现异常,导致没有delete掉。

3、实现

1.确定对象被使用之前已被初始化,最好在用对象的时候,再声明与定义。

  • 为内置型对象进行手工初始化,因为C++不保证初始化他们。
  • 构造函数最好使用成员初值列,而不要在构造函数本体内使用赋值操作。初值列列出的成员变量,其排列次序应该和它们在class中的声明次序相同。
Class Test{Public:
Test(int a,int b):x(a),y(b){}
Private:
Int x,y;
}
  • 为免除“跨编译单元之初始化次序”问题,请以local static 对象替换non-local static 对象。

2.尽可能延后变量定义式的出现时间。
这样做可增加程序的清晰度并改善程序效果。

3.尽量少做转型动作

  • 如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts。如果有个设计需要转型动作,试着发展无需转型的替代设计。
  • 如果转型是必要的,试着将它隐藏在某个函数后面。客户税后可以调用这个函数,而不需要将转型放入他们自己的代码。
  • 宁可使用C++转型,也不使用旧时转型。前者容易辨识出来。

4.避免返回handles指向的对象内部成分

  • 避免返回handles(包括引用,指针,迭代器)指向对象内部。遵守这个条款可增加封装性。帮助const成员函数的行为像个const,并将发生“虚吊号码牌”的可能性降至最低。

5.为“异常安全”而努力是值得的

6.透彻了解inline的里里外外

  • 将大多数inline限制在小型,被频繁调用的函数身上。
  • 不要只因为function templates出现在头文件中,就将他们声明为inline。

7.将文件间的编译依存关系降到最低

  • 支持“编译依存性最小化”的一般构想是:想依与声明式而不是定义式。基于此构想的2个手段是handle class和接口类
  • 程序库头文件应该以“完全且仅有声明式”的形式存在,这种做法不论是否涉及templates都使用。

4、模板与泛型编程

1.了解隐式接口和编译期多态

  • Class和template都支持接口和多态。
  • 对于class而言接口是显示的,以函数签名为中心。多态这是通过virtual函数发生于运行期。
  • 对于tempalte参数而言,接口是隐式的,奠基于有效表达式。多态则是通过template具现化和函数重载解析发生于编译期。

2.了解typename的双重意义

  • 请使用关键字typename标识嵌套从属类型名称:但不得在base class lists或member initialization内以他作为base class修饰符。

3.学会处理模板化基类内的名称

4.将与参数无关的代码抽离template

  • Template生成多个classes和多个函数,所以任何template代码都不该与某个构成膨胀的template参数产生相依关系。
  • 因非类型模板参数而造成的代码膨胀,往往可消除。做法是以函数参数或class成员变量替换template参数。

5.运用成员函数模板接受所有兼容类型
6.需要类型转换时请为模板定义非成员函数。
7.请使用traits class表现类型信息。
8.认识template元编程。

5、定制new和delete

1.了解new-handler的行为
2.了解new和delete的合理替换时机。
3.编写new和delete时需要固守常规
4.写了placement new也要写placement delete

6、其他

1.不要忽视编译器的警告
2.让自己熟悉boost
3.让自己熟悉包括TR1在内的标准程序库

Effective C++条款粗略总结相关推荐

  1. effective c++条款11扩展——关于拷贝构造函数和赋值运算符

    effective c++条款11扩展--关于拷贝构造函数和赋值运算符 作者:冯明德 重点:包含动态分配成员的类 应提供拷贝构造函数,并重载"="赋值操作符. 以下讨论中将用到的例 ...

  2. Effective C++条款09:绝不在构造和析构过程中调用virtual函数

    Effective C++条款09:绝不在构造和析构过程中调用virtual函数(Never call virtual functions during construction or destruc ...

  3. effective c++条款44 将与参数无关的代码抽离templates

    effective c++条款44 将与参数无关的代码抽离templates 首先了解这个条款的含义:使用template可能导致代码膨胀,二进制码会带着重复(或者几乎重复)的代码.数据,或两者.其结 ...

  4. Effective C++ 条款02:尽量使用const,enum,inline替换#define

    Effective C++ 条款02:尽量使用const,enum,inline替换#define 用另一句话说:用编译器代替预处理器比较好. 举个例子:加入定义一个常量: #define ASPEC ...

  5. Effective C++条款05:了解C++默默编写并调用哪些函数(Know what functions C++ silently writes and calls)

    Effective C++条款05:了解C++默默编写并调用哪些函数(Know what functions C++ silently writes and calls) 条款05:了解C++默默编写 ...

  6. Effective C++条款40:明智而审慎地使用多重继承(Use multiple inheritance judiciously)

    Effective C++条款40:明智而审慎地使用多重继承(Use multiple inheritance judiciously) 条款40:明智而审慎地使用多重继承 1.多重继承的两个阵营 2 ...

  7. Effective C++条款39:明智而审慎地使用private继承(Use private inheritance judiciously)

    Effective C++条款39:明智而审慎地使用private继承(Use private inheritance judiciously) 条款39:明智而审慎地使用private继承 1.pr ...

  8. Effective C++条款20:宁以pass-by-reference-to-const替换pass-by-value

    Effective C++条款20:宁以pass-by-reference-to-const替换pass-by-value(Prefer pass-by-reference-to-const to p ...

  9. Effective C++条款30:透彻了解inlining的里里外外(Understand the ins and outs of inlining)

    Effective C++条款30:透彻了解inlining的里里外外(Understand the ins and outs of inlining) 条款30:透彻了解inlining的里里外外 ...

最新文章

  1. CISC-235 Fall 2018 Assignment
  2. java父系调用子系,获取usb设备父系或子代
  3. Spring Boot 5:应用程序启动时初始化资源
  4. 【渝粤题库】广东开放大学 物业财税管理基础 形成性考核 (2)
  5. 网管实战之使用RSA实现企业安全访问
  6. 设计模式---享元模式(C++实现)
  7. linux查看进程占用内存与ps命令
  8. javaMail学习(一)——易邮邮件服务器的使用
  9. 色温CCT与色坐标xy互换
  10. 从强化学习的角度看alphago与MCTS
  11. mt6577驱动开发 笔记版
  12. 课题组亓林博士的论文被 IEEE TGRS 录用
  13. 【粉丝福利,限时免费】【千里之行,始于脚下】我在CSDN上的精品博文汇总,收藏起来慢慢看
  14. 小米与摩托罗拉的隔空充电技术,或是行业下一个突破点
  15. java生成word 带表格_【java】Freemarker 动态生成word(带图片表格)
  16. 数据库中内连接、外连接、全连接
  17. CF633C Spy Syndrome 2 ACA+DP
  18. 保证良好睡眠,是糖友逆糖的关键
  19. day15 计算圆周率
  20. \t\t把超星图书虚拟打印为PDF格式,实现永久阅读

热门文章

  1. 虚拟机 host-only网络配置
  2. java基础(三):java面向对象OOP
  3. 使用各种姿势舒服的部署微前端项目(上:打包与上传)
  4. 安装向日葵远程后电脑亮度和夜间模式不能使用了——故障笔记
  5. 在linux下恶臭hellotext中作用的?,《Linux内核与程序设计》实验学习笔记
  6. Imagination和浙江大学信电学院签署合作协议,校企共创大学课程新篇章
  7. Alpha版本冲刺(二)
  8. VPP协议栈学习一:snd_wnd
  9. Vue实现在线编辑excel
  10. python修改图片类型