EC读书笔记系列之9:条款16、17
条款16 成对使用new和delete时要采取相同形式
记住:
★若你在new表达式中使用[ ],必须在相应的delete中也使用[ ],反之亦然
------------------------------------------------------------------
当结合typedef使用时,应特别注意:如:
typedef std::string AddressLines[4];
std::string *pal = new AddressLines; //等同于new string[4]
delete pal; //错误
delete [] pal; //正确
条款17 以独立语句将newed对象置入智能指针
记住:
★以独立语句将newed对象置入智能指针内,若不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏
---------------------------------------------------------------------------------
问题背景:
void processWidget( std::tr1::shared_ptr<Widget> pw, int priority );
使用时:
processWidget( new Widget, priority() ); //无法通过编译,因为传入的类型不对
processWidget( std::tr1::shared_ptr<Widget>( new Widget ), priority() ); //可以
但这种调用可能泄漏资源:原因如下:
std::tr1::shared_ptr<Widget>( new Widget )对这句话,编译器工作时拆成两部分
·执行new Widget表达式;
·调用tr1::shared_ptr构造函数
于是在调用processWidget之前,编译器需创建代码,做以下三件事
·调用priority函数
·执行new Widget表达式;
·调用tr1::shared_ptr构造函数
然而编译器以何种顺序来完成以上三件事却不一定,假设是下面这样的顺序:
·执行new Widget表达式;
·调用priority
·调用tr1::shared_ptr构造函数
万一调用priority函数时出现异常,则new Widget返回的指针将遗失,∵其尚未被置入shared_ptr内。
避免方法:使用独立语句:
std::tr1::shared_ptr<Widget> pw( new Widget ); //在单独语句内以智能指针存储newed所得对象,此即本条款主题
processWidget( pw, priority() ); //这个调用动作绝不至于造成泄漏