Effective C++ 50条款
条款1:尽量用const和inline而不用#define
以const 行使常量折叠,用inline 代替常用操作的宏定义,而且库里面有很多常用函数可用。当然不能抛弃宏,宏还是很有用滴。偶最近才发现宏的可爱之处。。。咔咔。
条款2:尽量用而不用
iostream的 IO智能,灵活,类型安全。呃,效率要比 stdio的IO低些。
条款3:尽量用new和delete而不用malloc和free
new/delete是转为C++设计的---它会自动调用构造析构函数。
恩,这也会造成不必要的性能损失。当new一个自定义类型的数组时,会调用类的默认构造函数,这时构造的对象往往不是所需要的---也就是所那些默认构造函数白调用了。这个问题可用C++的定位new表达式解决,然后需要时再在分配的内存上构造对象。删除时直接删除整块内存。不过偶在VC6下测试时发现析构函数没用调用,可能析构函数需要显式调用吧,这种情况岂不是跟用malloc/free时一样,那拿定位new表达式干嘛? orz---呃,除了这两种情况,任何情况下都不应显示调用析构函数,不然你会后悔的。
条款4:尽量使用c++风格的注释
一条无聊的条款,使用什么注释要看程序员的喜好与具体情况的。
条款5:对应的new和delete要采用相同的形式
就是new/delete,
new[]/delete[], malloc/free, calloc/free, ralloc/free必须配对。
条款6:析构函数里对指针成员调用delete
呃,在构造函数中分配资源,在析构函数中释放资源。这个与异常,new动态分配等合作得天衣无缝。
条款7:预先准备好内存不够的情况。
为了程序健壮点,进行错误检查是需要的。特别是new,万一抛出异常就不好玩了,虽然现在内存很便宜,很多人有海量内存。
条款8: 写operator
new和operator delete时要遵循常规。
条款9: 避免隐藏标准形式的new
条款10: 如果写了operator
new就要同时写operator
delete
自己做了什么事自己最清楚,解铃还需系铃人。
条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符。
如果你知道不遵守这条规则使偶对着仅仅1000多行的代码调试了两天,你就知道不遵循这条条款的后果了。编译器很生气,后果很严重。
条款12: 尽量使用初始化而不要在构造函数里赋值。
对于自定义类型,在构造函数里复制会调用默认构造函数与拷贝构造函数,而那次默认构造函数的调用时不必的。所以初始话效率高的多,特别是大型复杂对象。但对于预定义类型则不需要,太多东东在初始化列表会搞的乱七八糟。
条款13: 初始化列表中成员列出的顺序和它们在类中声明的顺序相同。
因为类数据成员是按类声明中的顺序初始化的。遵循这条条款可以避免很多可怕的运行错误。
条款14: 确定基类有虚析构函数。
这是所有对象都能正常析构的保证。
条款15: 让operator=返回*this的引用。
所有重载运算符的行为都必须与预定义运算符的行为一致。为了能连续调用operator=(),必须让其返回*thist引用,不能是其它。
条款16: 在operator=中对所有数据成员赋值
对于有继承的情况,派生类的赋值运算符要调用基类的赋值运算符。保证基从类数据继承下来的数据成员正确复制。
条款17: 在operator=中检查给自己赋值的情况
有些operator=需要先释放自己占用的资源再进行赋值操作,此时这条款就成了必须了。免得搞得半死不活。
条款18: 争取使类的接口完整并且最小。
完整是显然的,没有完整接口的类拿来干嘛? 但完整的同时要保持的接口的最小化。类的接口太大难于掌握,而且容易引起歧义。最好是只提供一些原子操作。需要的话可提供一些常用复合操作以增加效率。
条款19: 分清成员函数,非成员函数和友元函数
条款20: 避免public接口出现数据成员
这是所有面向对象技术所BS的行为。不但丧失了类“封装”这一重要作用,而且容易出错。
条款21: 尽可能使用const
在所有能用const的地方都应加上const,包括数据定义声明,类函数成员声明。这样可避免一些可怕的运行错误而不会造成性能上的损失。多打几个字的代价肯定能赚回来。
条款22: 尽量用“传引用”而不用“传值”。
效率,效率,效率还是效率。呃,还要记住的是在能加const的地方都要加上, const引用
条款23: 必须返回一个对象时不要试图返回一个引用
这条条款是为效率狂准备的。任何时候返回一个临时对象的引用或地址都是可怕的行为。
条款24: 在函数重载和设定参数缺省值间慎重选择
条款25: 避免对指针和数字类型重载
条款26: 当心潜在的二义性。
条款27: 如果不想使用隐式生成的函数就要显式地禁止它。
如默认构在函数,拷贝构造函数,复制运算符,析构函数。。。。禁止很简单。声明为privated,并不提供定义。。。咔咔。。。当然有些时不能禁止的。如果不放心隐式生成的函数,那就自己提供一个。特别是有指针的时候。
条款28: 划分全局名字空间。
全局域只有一个。污染全局域的后果很严重。这里namespace正好派上用场了。
条款29: 避免返回内部数据的句柄。
条款30: 避免这样的成员函数:其返回值是指向成员的非const指针或引用,但成员的访问级比这个函数要低。
条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用
很明显返回局部变量的引用或地址得到的将是垃圾。 函数也不应该返回new来的对象的引用或地址。函数不一定是只有你用的,使用者不知道你的函数的实现方式,当然也不会轻易的动用delete咯,这也就造成了内存泄漏。 即使使用者这是你一个人,当函数的返回值散步与程序各处时,什么时候delete不是一个容易的判断。
条款32: 尽可能地推迟变量的定义
条款33: 明智地使用内联
内联可以避免函数调用的开销。短小常用的函数都应该内联。如果内联函数体非常短,编译器为这个函数体生成的代码就会真的比为函数调用生成的代码要小许多。这种情况,内联这个函数将会确实带来更小的目标代码和更高的缓存命中率!但在很多情况下,那内联都会增加代码体积。在一台内存有限的计算机里,过分地使用内联所产生的程序会因为有太大的体积而导致可用空间不够。即使可以使用虚拟内存,内联造成的代码膨胀也可能会导致不合理的页面调度行为(系统颠簸),这将使你的程序运行慢得象在爬。(当然,它也为磁盘控制器提供了一个极好的锻炼方式:))过多的内联还会降低指令高速缓存的命中率,从而使取指令的速度降低,因为从主存取指令当然比从缓存要慢。
还有就是
inline 只是程序员对编译器的建议,但决定权在编译器手上,当编译器认为你的函数不适合内联时。它就会以普通函数的形式处理你的函数,这样可能会带来函数重定义的错误。
构造函数和 析构函数不适于内联,因为这些函数的代码往往比你所看到的多。
最后一个就是有静态数据成员的函数和虚函数不能作为内联函数
条款34: 将文件间的编译依赖性降至最低
条款35: 使公有继承体现
"是一个"
的含义
条款36: 区分接口继承和实现继承
条款37: 决不要重新定义继承而来的非虚函数
条款38: 决不要重新定义继承而来的缺省参数值
条款39: 避免
"向下转换"
继承层次
条款40: 通过分层来体现
"有一个"
或 "用...来实现"
条款41: 区分继承和模板
条款42: 明智地使用私有继承
条款43: 明智地使用多继承
条款44: 说你想说的;理解你所说的
条款45: 弄清C++在幕后为你所写、所调用的函数
条款46: 宁可编译和链接时出错,也不要运行时出错
运行错误当然比编译连接错误麻烦多了。可是这条款是一句废话。错误是能选择的么?
条款47: 确保非局部静态对象在使用前被初始化
这句话好像应该说成:非静态局部变量和动态分配的对象使用前应初始化。非静态局部变量和动态分配的变量都是为初始化的,使用前当然应该初始化咯。全局变量和静态变量自动初始化为0。
条款48: 重视编译器警告
条款49: 熟悉标准库
标准库是个好东东。。。。咔咔
条款50: 提高对C++的认识
这不是废话么?呃。。。C++确实蛮复杂。 理解C++最好理解它的历史《The Design and
Evolution of C++》。呃。C++标准是最权威的手册。(两个偶都不喜欢看,D&E太无聊,标准太拗口。。。。 到时《The C++ programing language》《C++primer》《Inside The C++ Object Model》 和“深入C++系列”都很不错,呃。。。
Effective C++ 50条款的更多相关文章
- Effective C++:条款28:避免返回 handles 指向对象内部成员
(一) 有时候为了让一个对象尽量小,能够把数据放在另外一个辅助的struct中,然后再让一个类去指向它.看以下的代码: class Point { public: Point(int x, int y ...
- 《MORE EFFECTIVE C++》条款20 条款21
条款20 协助编译器实现返回值优化 当重载运算符的时候,比如+ - * / 这类运算符,该函数返回的值一定是个右值(即不能是引用),那么执行一次运算的开销可能会在临时对象上调用多次构造函数和析构函数, ...
- 《More Effective C++》 条款5 谨慎定义类型转换函数
---恢复内容开始--- C++编译器能够在两种数据类型之间进行隐式转换(implicit conversions),它继承了C语言的转换方法,例如允许把char隐式转换为int和从short隐式转换 ...
- 《Effective C++》条款26 防卫潜伏的ambiguity模棱两可的状态
每个人都有思想.有些人相信自由经济学,有些人相信来生.有些人甚至相信COBOL是一种真正的程序设计语言.C++也有一种思想:它认为潜在的二义性不是一种错误.ambiguity 这是潜在二义性的一个例子 ...
- 《Effective C++》条款14 总是让base class拥有virtual destructor
有时,一个类想跟踪它有多少个对象存在.一个简单的方法是创建一个静态类成员来统计对象的个数.这个成员被初始化为0,在构造函数里加1,析构函数里减1.(条款m26里说明了如何把这种方法封装起来以便很容易地 ...
- Effective C++:条款37:绝不又一次定义继承而来的缺省參数值
因为又一次定义继承而来的non-virtual函数是不对的(见上一个条款),所以这个条款就将问题局限于:绝不又一次定义继承一个带有缺省參数值的virtual函数. (一) virtual函数是动态绑定 ...
- Effective C++:条款25:考虑写出一个不抛异常的swap函数
(一) 缺省情况下swap动作可由标准程序库提供的swap算法完毕: namespace std { template<typename T> void swap(T& a, T& ...
- Effective C++:条款14:在中小企业资源管理copying表现
(一) 在一项条款说法auto_ptr和tr1::share_ptr适合heap-based资源.然而,并非所有的资源都heap-based的.换句话说不tr1::shared_ptr 和 auto_ ...
- More Effective C++ 35 条款
一.基础议题(basics) 条款1:仔细区别 pointers 和 references(Distinguish between pointers and references) 一个基本的语法问题 ...
随机推荐
- ContentControl as CC和ContentPresenter as CP的使用
1.CC为文本控件的父类,它继承为control,所以他是控件, 2.CP继承FrameworkElement,所以他是容器,相当于占位符 3.想让控件中能包含子控件就需要用CP,反之用CC就行.(不 ...
- 使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
先来看看下面实时效果演示: 用户点击编辑时,在点击行下动态产生一行.编辑铵钮变为disabled.新产生的一行有更新和取消的铵钮,点击“取消”铵钮,删除刚刚动态产生的行.编辑铵钮状态恢复. 更新与删除 ...
- JavaScript中标识符的命名
JavaScript中的标识符的命名有以下规则: 由字母.数字.$._组成 以字母.$._开头 不可以使用保留字!!! 要有意义!!!!!!! 标识符的命名规范: 1.驼峰命名法 除标识符的第一个单词 ...
- 修改tomcat默认端口号
修改tomcat端口号 端口修改tomcat tomcat服务器的默认端口号是8080 1 只启动一个tomcat的情况 当我们不想使用8080端口,需要修改为其他端口时,我们可以: 1, 打开tom ...
- jQuery的ajax的post请求json格式无法上传空数组
问题描述:在和后端对接时,使用jquery的ajax的post方式向后端传递一序列约定好格式的对象数组.遇到了一个现象:如果对象中的数组是空数组,那么在请求参数中是不会出现的. 以下是数据的对比: ...
- Linux链接脚本学习--lds(转)
Linux链接脚本学习--lds 一.概论 ld: GNU的链接器. 用来把一定量的目标文件跟档案文件链接在一起,并重新定位它们的数据,链接符号引用. 一般编译一个程序时,最后一步就是运行ld进行链接 ...
- [原创]K8 Struts2 Exp 20170310 S2-045(Struts2综合漏洞利用工具)
工具: K8 Struts2 Exploit组织: K8搞基大队[K8team]作者: K8拉登哥哥博客: http://qqhack8.blog.163.com发布: 2014/7/31 10:24 ...
- Java 内存分配及垃圾回收机制初探
一.运行时内存分配 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域. 这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则 ...
- ADO.NET 4.5中的异步与流特性
.NET 4.5为仍在选择直接与DataReader系列类打交道的.NET开发人员带来了一些新的异步与流特性支持.SqlDataReader允许开发人员在减少一些便利性的基础上获得更好的性能.例如,该 ...
- JavaScript -- FileSystemObject-文件夹
-----057-FileSystemObject-文件夹.html----- <!DOCTYPE html> <html> <head> <meta htt ...