改善C++代码的学习笔记2
来源:互联网 发布:mac 10.12 dns flush 编辑:程序博客网 时间:2024/05/21 17:13
1、使用typedef与#define提高可读性
对于某些复杂难懂的指针,如void (*p[10]) (void(*)()),谁知道这什么东西?第一个括号中的*p[10]是指针数组,数组中的指针指向以void(*)()为参数的函数,而这个参数void(*)()又是一个指向无参数、无返回的函数指针。对于这些可读性太纠结的东西,我们可以这样来:typedef void (*pfv)()声明无参无返回的函数指针,typedef void (*Keypoint)(pfv)声明指向参数为pfv且无返回的函数指针,Keypoint p[10],终于搞定。 在此处得说明一下,如果有这么两句typedef int* PINT与#define PINT int*的话,请注意,PINT p1,p2可能会让你失望了。如果用的是typedef那会有两个指针,如果是#define会有一个指针与一个整型变量。原因在于typedef一定的封装性。
2、优先使用前缀操作符
这里以自增运算符为例,有能力的同学可以考虑从汇编的角度去比较一下,这里从表面来看看。运行操作符前编译器要去寻找相关的函数,不论前缀还是后缀,都是只有一个参数。为了区别,C++规定后缀形式有一个int型的参数,由编译器传递一个0给该函数。那么我们来比较一下两者的区别吧:
//成员函数重载<类型> ClassName::operator ++();//前缀<类型> ClassName::operator ++(int);//后缀//非成员函数重载<类型> operator ++(ClassName&);//前缀<类型> operator ++(ClassName&,int);//后缀//后缀,构造临时对象保存原值,自增,返回临时对象//前缀,自增,返回
虽然可能效率上相差不大,但既然有省事的好办法,何乐而不为呢?
3、区分new的三种形态
new operator/operator new/placement new三种形态。可能我们常见的就是类似于int *ptr=new int类的写法,同时我们也曾写下过classname *ptr=new classname(……)创建一个对象,这就是new operator向内存进行申请。但申请内存又调用operator new,有点重载函数的意思,即void* operator new(size_t size)。而最后一种placement new是C++标准库的一部分,用它来选择合适的构造函数,如果想对未初始化的内存进行处理取得想要的对象,就这样干吧:
#include#include "classA.h"int main(){ void *s=operator new ( sizeof(A) ); A *p=(A*) s; new (p) A(2012);//神奇的使用方法 …… return 0;}
真的是哥第一次见到这种东西,new (p) A(2012)在特定的内存上用特定的构造函数创建了一个对象,希望自己手动管理内存就用placement new。总结一下:1、在堆上建立对象,用new operator实现;2、仅仅分配内存,不干其它事,operator new,当然,不满意的话自己重载一个;3、已有内存建立对象,placement new,通常不这么干。
4、正确处理new的失败
面对new的失败,平日里常用if(!ptr){……}等语句。虽然至今没见到过它申请失败的样子,但是对于现在的new而言,它并不会返回一个NULL的指针,反而是抛出一个std::bad_alloc的异常,那么我们就应该采取新式的捕捉异常了:try{int* ptr=new int;……}catch(std::bad_alloce){return false;}。当然了,古老的编译器仍会有返加NULL的情况,但新式的编译器……呵呵,哥没试过。。。
5、掌握定义变量的时机
C++允许在任意位置定义变量,在遇上定义时,调用相关的构造函数,消去时也会调用其相关的析构函数。在使用变量时,尽量避免其作用域的膨胀,不仅有效减少变量名污染,同时还有利于他人阅读理解。VC6.0中一个与VC2010明显的区别在于for(int i=0;i<N;i++),这里变量i的作用域在两个环境下是不一样的!总之,推迟变量的定义。
6、防止重复包含头文件
平时要#include “classA.h”时,万一这里面包含的与现有的发生重复,那就出错了。常用的办法是#ifdef <project>_<path>_<file>_h #define ……,当然了,还有一种#pragma once的方法。编译器每次编译时都要打开头文件才可判定是否有重复定义,故大项目里,#ifdef使编译时间较长,而#pragma once的方式由编译器提供,它保证同一个文件不会被包含多次(同一个文件是指物理上一,不是指内容相同的),这种方法在兼容性方面貌似表现不是很好,故常用前者的方法。
- 改善C++代码的学习笔记2
- 改善C++代码的学习笔记1
- 《重构 改善既有代码的设计》学习笔记 1
- 重构 改善既有代码的设计-学习笔记
- 阅读《重构 改善既有代码的设计》学习笔记
- 《重构-改善既有代码的设计》笔记2
- 《重构改善既有代码的设计》-代码的坏味道(学习笔记 )
- 重构-改善既有代码设计学习笔记(一)—代码的坏味道
- 读重构-改善既有代码的设计笔记
- 《重构 改善既有代码的设计》学习笔记 2 -- Extract Method(提炼函数)
- 学习 重构--改善既有的代码
- 《重构改善既有代码的设计》-重构原则(学习笔记)
- 《重构 改善既有代码的设计》——学习笔记(一)
- 《重构 改善既有代码的设计》——学习笔记(二)
- 编写高质量代码:改善Java程序的151个建议-学习笔记(1-4章)
- 编写高质量代码:改善Java程序的151个建议-学习笔记(5-8章)
- 编写高质量代码:改善Java程序的151个建议-学习笔记(9-12章)
- 《重构 改善既有代码的设计》——学习笔记(三)
- MongoDB java方法
- HTTP错误 大全 403 401 400 404 304 200
- 修改数据库中表的所有者为dbo。
- 项目计划管理软件:GanttProject
- vim 命令
- 改善C++代码的学习笔记2
- Shanghai ** Product Development Plan
- 我的yum配置
- Howto: receive mail and save attachment with fetchmail, procmail and metamail
- 浅谈inline HOOk之ring0下的进程保护
- Linux程序的安装
- 如何有效防止PHP木马对linux操作系统提权
- 整理我的264的模糊概念——请教小徐老师的心得
- 图片格式的PHP验证码的实现