要习惯使用智能指针,避免裸指针。
常见的智能指针有以下几种:
std::shared_ptr:(1)引用计数和被管理对象相互分离;容易引发内存碎片,尽量使用make_shared来优化。 (2)一旦一个对象进入了shared_ptr,就最好一直用shared_ptr相互传递。 (3)无法从this指针获得
boost::intrusive_ptr:(1)可以从this指针获得. (2)类需要继承自intrusive_ptr,无法管理已有的其他对象。
enable_shared_from_this: 类似于intrusive_ptr
unique_ptr:没有引用计数,额外开销很少,但资源是独享的
尽量避免使用C++异常
对于一些旧版本的glibc,异常库可能实现的不完善:多个线程在一段代码同时抛异常时,会导致死锁。
C++的语法对异常也不够友好:你无法从一个函数的签名中得知这个函数的异常返回情况,这就意味着假如你使用了别人的库,你相当于捧着一个不知道何时就会爆掉的炸弹。更进一步讲,任何无法从函数签名中获取异常返回情况的语言,都不应该使用异常,除非你不在意你的程序崩溃掉。在C++11里,关键字“noexcept”缓解了这一问题,但最优的方案是java的。
假如我们一定要返回异常,请在注释里说明清楚。
没有异常的C++库里,请管理好自己的ErrorCode。最好集中定义一个类来管理这些错误,并且定义合适的函数来打印这些错误。
RETURN_NOT_OK(ErrorCode)的宏,对于异常free的代码是非常有用的。
如果遇到了处理不了的bug,就用assert来把程序crash掉。crash之前记得打印充足的log。
要善于利用C++ RAII的思想
(1) 尽量不要手动lock/unlock、 create/delete,而通过一个辅助类的构造和析构
(2) 假如想统计某个函数在执行时间,也可以在函数入口处创建一个辅助类,利用构造和析构来计算时间。
网友评论