免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3433 | 回复: 8
打印 上一主题 下一主题

[C++] c++构造函数要try catch 还是直接throw [复制链接]

论坛徽章:
7
摩羯座
日期:2013-12-05 10:42:57辰龙
日期:2013-12-27 13:40:49亥猪
日期:2014-01-15 09:10:37天秤座
日期:2014-01-20 11:22:20辰龙
日期:2014-01-26 17:02:25午马
日期:2014-01-27 14:22:34水瓶座
日期:2014-02-19 09:36:40
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-11-13 10:38 |只看该作者 |倒序浏览
有个问题比较疑惑,现有个类

class test
{
public:
   test(uint32_t num) {
     if (num ==0) {
       //如果输入为0 怎么办?
    }
    m_pdata = new int[num];
   //如果new失败怎么办?
  }
private:
  int *m_pdata;
}

大牛支招

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2015-11-13 11:03 |只看该作者
抛异常就不会调用析构了,如果没事就抛吧;如果后续可以判断未初始化好就catch住吧。

建议增加一个初始化函数更好些。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
3 [报告]
发表于 2015-11-13 16:29 |只看该作者
本帖最后由 windoze 于 2015-11-13 16:35 编辑

构造函数里抛异常会让你有一个半截子对象,而且也不会调用这个对象的析构函数。
但是每个数据成员的析构函数都会被调!
但是每个数据成员的析构函数都会被调!
但是每个数据成员的析构函数都会被调!
重要的事情说三遍!
也就是说,只要你保证对象里的每个数据成员都符合RAII的要求,就不会有资源泄漏。
比如说你的对象里有一个unique_ptr,那么如果你在构造函数里抛出了异常,这个unique_ptr会正确的处理这种情况,如果它此时已经构造好,指向一个有效的对象,那么这个对象会析构,否则就什么也不做。
这个故事告诉我们,不要使用裸指针管理资源,像lz贴的那段代码就会烦死鸟挖,改成这样就能少烦一点了:

  1. class test
  2. {
  3. public:
  4.     test(uint32_t num)
  5.     {
  6.         if (num ==0) {
  7.             //如果输入为0 怎么办?
  8.             throw(...);
  9.         }
  10.         m_pdata.reset(new int[num]);
  11.     }
  12. private:
  13.     std::unique_ptr<int[]> m_pdata;
  14. }
复制代码
由于new能正确处理0长度数组,所以程序可以简化成这样:

  1.     test(uint32_t num) : m_pdata(new int[num]) {
  2.         // ...
  3.     }
复制代码
如果new失败什么事也不会有

论坛徽章:
7
摩羯座
日期:2013-12-05 10:42:57辰龙
日期:2013-12-27 13:40:49亥猪
日期:2014-01-15 09:10:37天秤座
日期:2014-01-20 11:22:20辰龙
日期:2014-01-26 17:02:25午马
日期:2014-01-27 14:22:34水瓶座
日期:2014-02-19 09:36:40
4 [报告]
发表于 2015-11-13 16:32 |只看该作者
使用裸指针管理资源, 怎么理解?!

回复 3# windoze


   

论坛徽章:
7
摩羯座
日期:2013-12-05 10:42:57辰龙
日期:2013-12-27 13:40:49亥猪
日期:2014-01-15 09:10:37天秤座
日期:2014-01-20 11:22:20辰龙
日期:2014-01-26 17:02:25午马
日期:2014-01-27 14:22:34水瓶座
日期:2014-02-19 09:36:40
5 [报告]
发表于 2015-11-13 16:36 |只看该作者
我理解你的意思了,但是我们基于redhat6.3做的开发,我也想用智能指针,但是redhat6.3的gcc不支持c++11.
回复 3# windoze


   

论坛徽章:
7
摩羯座
日期:2013-12-05 10:42:57辰龙
日期:2013-12-27 13:40:49亥猪
日期:2014-01-15 09:10:37天秤座
日期:2014-01-20 11:22:20辰龙
日期:2014-01-26 17:02:25午马
日期:2014-01-27 14:22:34水瓶座
日期:2014-02-19 09:36:40
6 [报告]
发表于 2015-11-13 16:38 |只看该作者
我觉得二楼的提供的办法最好,也是我最常用的,加个初始化函数.

回复 3# windoze


   

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
7 [报告]
发表于 2015-11-13 16:42 |只看该作者
回复 5# kdkgod

老版本的GCC可以用boost.smart_ptr里面的scoped_ptr凑合一下,在这个场合没什么区别。

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
8 [报告]
发表于 2015-11-13 16:45 |只看该作者
回复 6# kdkgod

不过话说回来,你干吗不用vector<int>?这个再老版本的C++也该有了。

论坛徽章:
7
摩羯座
日期:2013-12-05 10:42:57辰龙
日期:2013-12-27 13:40:49亥猪
日期:2014-01-15 09:10:37天秤座
日期:2014-01-20 11:22:20辰龙
日期:2014-01-26 17:02:25午马
日期:2014-01-27 14:22:34水瓶座
日期:2014-02-19 09:36:40
9 [报告]
发表于 2015-11-13 16:54 |只看该作者
历史原因,
我实现了一个基于数组的无锁的缓冲区模板类. 数组的size是用过template传,但是这样编译之后就指定了数组的大小,为了以后能通过配置文件灵活改变缓冲区大小,所以才这样的方式传数组的大小.


回复 8# windoze


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP