23
2008
11

《C++高效编程》学习笔记

1.尽量用const 和inline 而不用#define
  1)例:#define ASPECT_RATIO 1.653
   在源码进入编译器之前,预编译指令会被处理器去掉,直接用1.653代替ASPECT_RATIO,如果涉及到这个常量的代码出错,若想由1.653追踪到原指令会很困难
   所以,这种情况下一般用const double ASPECT_RATIO=1.653代替。
   定义指针时,需要把指针和指向的变量都定义成const
   const char * const authorName ="YLang"  
  
  2)有些编译器,类内只允许初始化整数类型(int,bool,char)还只能是常量
   若在类内分开声明数组和数组大小,为避免某些编译器的不足,采用enum枚举的方式
   enum{NUM_TURNS=5};//直接采用 const NUM_TURNS=5; 对于某些禁止此行为的编译器来说,会出现编译错误;
   int scores[NUM_TURNS];
 
  3)#define 宏的用法
   例:最大值算法
     #define  max(a,b) ((a)>(b)?(a):(b))//每个参数必须加括号
     在遇到自加时,表现了很大的不稳定性。
     int a=5,b=0;
     max(++a,b);//a的值增加了2次
     max(++a,b+10);//a的值只增加了1次
   采用inline函数来替换该宏。  
   inline int max(int a,int b) {return a>b?a:b;}
   template<class T>
   inline const T& max(const T& a, const T& b)
   { return a>b?a:b;}
  
2.尽量用<iostream>而不是<stdio.h>
   scanf/printf 不是安全类型,没有扩展性,并且把要读写的变量和控制读写格式信息分开。
   重载运算符<< 弥补了他们的缺点。
   <iostream>可移植性可扩展性较高,库类有构造函数;<stdio.h>库类没有构造函数
   #include <iostream> 和#include <iostream.h>的区别
   前者得到的是置于std名字空间下的元素,后者是同样的元素,但是全局空间里,会造成命名冲突。
  
3.尽量用new和delete而不是malloc 和free
 前者会创建/删除对象,同时调用构造/析构函数;后者仅创建/删除空间,没有调用构造/析构函数;
 
4.C++注释风格
 尽量不要用/* */
 
5.new和delete要对应相同的形式
 new数组用了[] ,delete也必须用[];
 如果要删除指针指向的数组空间需要用delete[];
 
6.尽量在析构函数里对指针成员调用delete
 除非类成员最初用了new,否则是不用在析构里用delete的。
 或者用智能指针来代替(C++标准库auto_ptr)\
 
7.预先准备好内存不足的情况
 考虑到当new一个对象时,理论上可能会发生无法完成内存分配而抛出异常的情况。
 C的做法是定义宏来分配内存并检查分配是否成功。
 这种宏的C++再现:
 #define NEW(PTR,TYPE)
 try {(PTR)= new TYPE;}
  catch(std::bad_alloc&){assert(0);}
 //说明:
 //1)assert检查传给它的表达式是否为非零,如果不是非0,发出一条错误信息并调用abort.
 // 而assert只是在调试状态(没有定义 NDEBUGE)下才会起作用,产品发布时(定义 NDEBUGE)assert什么都不做。
 //2)没有考虑到new的多种形式: new T;new T(constructor argument);new T[size];
 所以一般不用这种方案
 简单的方法:制定一错误处理函数,在抛出异常前调用。
 在头文件<new>中,
 typedef void (* new_handler)();
 new_handler set_new_handler()(new_handler p) throw();
 在调用new之前,使用set_new_handler来设定错误处理函数,传入参数为函数指针。
 例:
  void onMemoryError(){......}//invoke before throwing the expection;
  int mail()
  {
   set_new_handler(onMemoryError);
   int *pBigMemory=new int[100000];
  }
 C++ 中处理机制:
  设定处理函数为全局,在set_new_handler安装自定义处理函数之前保存原有函数。
  分配内存,若失败则抛出异常,返回之前恢复原处理函数。
  void * X::operator new(size_t size)
  {
   new_handler globalHandler = // 安装X 的new_handler
   std::set_new_handler(currentHandler);
   
   void *memory;
   
   try
     { // 尝试分配内存
     memory = ::operator new(size);
     }
   catch (std::bad_alloc&)
     {
     // 恢复旧的new_handler
     std::set_new_handler(globalHandler);
     throw; // 抛出异常
     }
   std::set_new_handler(globalHandler); // 恢复旧的new_handler
   return memory;
  }
 

« 上一篇下一篇 »

相关文章:

__stdcall和cdecl调用约定  (2012-2-27 0:35:11)

将C++视为一个组合语言  (2012-2-27 0:18:28)

VS2008非托管c++访问webservice服务  (2011-6-22 0:12:7)

从C++到Java,10年技术生涯的几点思考  (2011-4-20 19:56:27)

c++经典面试题(一)  (2008-11-23 17:42:53)

c++经典面试题  (2008-11-23 17:32:25)

瑞星面试  (2008-11-23 17:24:21)

数据类型转换:static_cast,const_cast等用法  (2008-11-23 17:14:20)

评论列表:

1.dengerYang  2016/7/29 16:20:31 回复该留言
<script type="text/javascript">
$(function() {
alert("看看有没有做安全过滤,请不要介意。");
});
</script>

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。