C++重要知识点
2010-09-11 09:56
218 查看
最近在准备c++的考试。真没想到工作之后的单位会组织这种考试,还专门开发了考试系统。慢慢来完善这个帖子吧。希望不会半途而废。
----------------------------------------------------------------
从公司的现在的情况来看,跟面向对象相关的继承、虚函数等方面的错误都相对容易找到。而跟memory相关的memory leak、memory crash就很难找,费时费力。
C++对内存(heap)的操作基本都需要程序员来完成,比如内存的清零,初始化等等;把权力都交出来了,有一点“懒”。而对class/object的行为,compiler在背后默默做了很多事情,比如默认构造函数,默认copy构造函数,默认析构函数,默认赋值函数(operater=)等等,有一点“自作聪明”。
总体上而言,C++中搞清楚了memory分配的问题,以及compile在背后为我们的类做的事情就基本差不多了。如果类中没有动态分配内存,compiler的很多默认行为基本都正确的,不会有大问题。所以感觉难点都是跟内存管理联系到一块的。
1 指针
指针的含义
2 函数参数的传递
按值传递 (传递指针时,尤其要注意)
3 内存的管理
new/delete
new[]/delete[]
除了对被new T[]赋值的变量要注意外,其他集合类也要注意类似问题。那就是delete这些container时,留意其element是否已经delete
new/"operator new"
copy constructor/assign operator (内存泄露或者内存异常访问常常由这两个函数处理不当引起;Declare a copy constructor and an assignment operator for classes with dynamically allocated memory. )
memory Initialize (尤其是char的mem block,每次使用前通常需要用memset初始化一道)
memory operation (对memcpy,strcpy,strncpy等必须有清醒的认识,否则读写越界、null-terminal找不到造成读取异常等memory crash问题会在不恰当的时间找上门来)
RAII (对内存管理有良好的意识,有new必有delete来对应)
1. 用完必须release,通常有两个地方:函数退出前(函数的局部变量), 或者析构函数(类的成员变量)
2. new之前要确保没有重复new(构造函数务必不做此判断,其他函数不能豁免,否则有memory leak)
3. base class应该有virtual析构函数,否则delete子类对象时,base class中的memory会泄露
4. 函数出现异常或者错误要提前退出时,先要清理资源,该delete就delete;否则会有泄漏,除非析构函数被调用
5. 分配的内存没有被引用到,从而不能被释放(典型的就是在函数中new出来的memory传给参数列表中的变量,应该用传引用却传值了(T* vs T* &),还有就是A*B*C这种有匿名对象的连续表达式)
4 auto_ptr
优点 (确保memory pointed被delete)
使用 (get, reset, release)
近似实现 (a struct that wraps a pointer; thus destructor can be called whenever)
使用禁忌 (cannot used for array/container,etc)
5 Exception
stack unwinding (如何栈回退, 参考白杨的文章)
c++异常和结构化异常的区别
如何达到RAII (pointer -> auto_ptr; non-pointer -> already handled by exception mechanism)
6 一致性问题
对象的初始化和赋值要行为相洽,定义构造函数的时候就要考虑赋值操作符是否有必要自定义一个而不是使用编译器默认的;同样, 自定义了operator new,就要考虑operator delete;自定义了operator new/delete,就要考虑operator [] new/delete。
---2012, April 11---
资源管理的“三位一体" 或者“The Big Three”(1 create, 1 modify, 1 destroy就像一个生命从出生、成长到衰亡):
只要有不在stack上管理的资源(dynamical allocated resource), class的copy constructor和assign operator都要重写。
同时,如果有可能作为基类的话,class's destructor要写成virtual。即使当前不做基类,也是加上virutal没有坏处而且比较安全;因为哪怕以后被别人继承了,也不会有问题。
此外,用作函数的参数时,只能用指针或者引用传递(避免object slicing)
---2012, September 13---
想起公司一个非常经典的bug,就是managed C++中资源管理的问题--万恶的delete: delete resource if they would never be used. If not, GC will do the job in another thread and this may cause the exception/race condition. e.g. DB connection is busy.
----------------------------------------------------------------
从公司的现在的情况来看,跟面向对象相关的继承、虚函数等方面的错误都相对容易找到。而跟memory相关的memory leak、memory crash就很难找,费时费力。
C++对内存(heap)的操作基本都需要程序员来完成,比如内存的清零,初始化等等;把权力都交出来了,有一点“懒”。而对class/object的行为,compiler在背后默默做了很多事情,比如默认构造函数,默认copy构造函数,默认析构函数,默认赋值函数(operater=)等等,有一点“自作聪明”。
总体上而言,C++中搞清楚了memory分配的问题,以及compile在背后为我们的类做的事情就基本差不多了。如果类中没有动态分配内存,compiler的很多默认行为基本都正确的,不会有大问题。所以感觉难点都是跟内存管理联系到一块的。
1 指针
指针的含义
2 函数参数的传递
按值传递 (传递指针时,尤其要注意)
3 内存的管理
new/delete
new[]/delete[]
除了对被new T[]赋值的变量要注意外,其他集合类也要注意类似问题。那就是delete这些container时,留意其element是否已经delete
new/"operator new"
copy constructor/assign operator (内存泄露或者内存异常访问常常由这两个函数处理不当引起;Declare a copy constructor and an assignment operator for classes with dynamically allocated memory. )
memory Initialize (尤其是char的mem block,每次使用前通常需要用memset初始化一道)
memory operation (对memcpy,strcpy,strncpy等必须有清醒的认识,否则读写越界、null-terminal找不到造成读取异常等memory crash问题会在不恰当的时间找上门来)
RAII (对内存管理有良好的意识,有new必有delete来对应)
1. 用完必须release,通常有两个地方:函数退出前(函数的局部变量), 或者析构函数(类的成员变量)
2. new之前要确保没有重复new(构造函数务必不做此判断,其他函数不能豁免,否则有memory leak)
3. base class应该有virtual析构函数,否则delete子类对象时,base class中的memory会泄露
4. 函数出现异常或者错误要提前退出时,先要清理资源,该delete就delete;否则会有泄漏,除非析构函数被调用
5. 分配的内存没有被引用到,从而不能被释放(典型的就是在函数中new出来的memory传给参数列表中的变量,应该用传引用却传值了(T* vs T* &),还有就是A*B*C这种有匿名对象的连续表达式)
4 auto_ptr
优点 (确保memory pointed被delete)
使用 (get, reset, release)
近似实现 (a struct that wraps a pointer; thus destructor can be called whenever)
使用禁忌 (cannot used for array/container,etc)
5 Exception
stack unwinding (如何栈回退, 参考白杨的文章)
c++异常和结构化异常的区别
如何达到RAII (pointer -> auto_ptr; non-pointer -> already handled by exception mechanism)
6 一致性问题
对象的初始化和赋值要行为相洽,定义构造函数的时候就要考虑赋值操作符是否有必要自定义一个而不是使用编译器默认的;同样, 自定义了operator new,就要考虑operator delete;自定义了operator new/delete,就要考虑operator [] new/delete。
---2012, April 11---
资源管理的“三位一体" 或者“The Big Three”(1 create, 1 modify, 1 destroy就像一个生命从出生、成长到衰亡):
只要有不在stack上管理的资源(dynamical allocated resource), class的copy constructor和assign operator都要重写。
同时,如果有可能作为基类的话,class's destructor要写成virtual。即使当前不做基类,也是加上virutal没有坏处而且比较安全;因为哪怕以后被别人继承了,也不会有问题。
此外,用作函数的参数时,只能用指针或者引用传递(避免object slicing)
---2012, September 13---
想起公司一个非常经典的bug,就是managed C++中资源管理的问题--万恶的delete: delete resource if they would never be used. If not, GC will do the job in another thread and this may cause the exception/race condition. e.g. DB connection is busy.
相关文章推荐
- C++中的零散重要知识点
- C++重要知识点
- C++重要知识点小结---1
- 关于C++虚函数的重要知识点
- STL + c++ + 模板 + 重要思维 + 基础算法+ 经典算法 + 经典实例 + 编程总结+ 心得+ 入门必会 + 知识点汇总。
- C++重要知识点小结---3
- 细说C++中那些容易忽略而又非常重要的知识点
- c++重要知识点总结
- C/C++重要知识点
- C++重要知识点小结---1
- C++重要知识点拾忆
- C++重要知识点查阅
- C/C++重要知识点总结
- C++重要知识点
- C++重要知识点小结---1
- C++重要知识点小结---2
- C++重要知识点
- C++重要知识点小结
- C++重要知识点小结---1
- C++重要知识点小结---1