免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: windyrobin
打印 上一主题 下一主题

C++ 这孩子 是不是误入歧途了? [复制链接]

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
41 [报告]
发表于 2011-11-30 11:26 |只看该作者
回复  zylthinking

将错误码一级一级地往上返回跟异常一层一层地往上抛有啥区别? 如果一个函数能不往上 ...
koolcoy 发表于 2011-11-30 11:15


区别就是错误码不反对就地处理错误, 用错误码就意味着错误的栈式处理, 层层处理; 而异常是能够一直向上冒的, 如果层层处理异常, 那异常除了写的代码量比error code 多些, 唯一剩下的大概就是放在 try{} 块里的对象自动销毁了。

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
42 [报告]
发表于 2011-11-30 11:34 |只看该作者
本帖最后由 koolcoy 于 2011-11-30 11:35 编辑

回复 41# zylthinking

懂了,原来你喜欢遇到错误就立即处理。我不喜欢这样,感觉太繁琐,这样容易遇到所谓的二八定理,就是80%的代码都在处理错误~~~

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
43 [报告]
发表于 2011-11-30 11:35 |只看该作者
本帖最后由 zylthinking 于 2011-11-30 11:39 编辑
回复  zylthinking

要想有新特性, 又能简洁明快……  这其实本来就是矛盾的……
OwnWaterloo 发表于 2011-11-30 11:22


不是必然矛盾的, struct 的 {.mem = value} 语法, 我觉得就是一个例子。
要我自己琢磨一个例子, 我倒是想把 construct 做一个修改, 让他带返回值; 如果返回 -1, 则编译器自动 free 内存, 然后让new 返回NULL那么:

A::A(){
    fd = open();
    if(fd == -1){
         throw xxx;
    }
}

然后

try{
    A* a = new A();
}catch(...){
    delete a;
}

这样的代码就完全可以 A* a = new A(); if(a == NULL){...}替代了
什么 std::nothrow, 让他见鬼去
哦, 错了, 什么 symbian 二段构造, 让他见鬼去

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
44 [报告]
发表于 2011-11-30 11:36 |只看该作者
回复  zylthinking

懂了,原来你喜欢遇到错误就立即处理。我不喜欢这样,感觉太繁琐。
koolcoy 发表于 2011-11-30 11:34


问题是, 你不立即处理, 非要冒几层后在一个地方处理, 那么错误上下文很可能丢失, 你处理完毕后也回不去了

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
45 [报告]
发表于 2011-11-30 11:37 |只看该作者
本帖最后由 OwnWaterloo 于 2011-11-30 11:41 编辑
对本质还是约定, 但约定太多了就是麻烦了。
zylthinking 发表于 2011-11-30 11:14


从上面的帖子, 我觉得其实你已经领悟到这部分的精髓了。
而具体的约定, 你这不都已经差不多记完了么……


OO理论的那种多态, 其实只是多态的一个分支:inclusion_polymorphism
如果还有兴趣, 可以看看这篇文章
《翻譯:多型不行時(When Polymorphism Fails )by Steve Yegge》
当它不行时, 解决方式就是另一分支: Parametric_polymorphism
ruby社区称其为duck tpying: 我不管你是不是鸭子类型, 只要你能叫, 我就当你是鸭子。
相比inclusion_polymorphism 是一种更松散、更灵活的约束: 需要什么就功能就提出什么约束, 不需要与具体类型绑死。

inclusion_polymorphism的优势就是能被静态类型语言高效的实现, 比如vptr+vtbl。
而duck tpying是运行时的事情了。
STL那种技巧, 我认为就是一种编译时的 duck tpying: 我不管你具体是什么类型, 只要你能够++, 就能for_each。

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
46 [报告]
发表于 2011-11-30 11:45 |只看该作者
从上面的帖子, 我觉得其实你已经领悟到这部分的精髓了。
而具体的约定, 你这不都已经差不多记完了么 ...
OwnWaterloo 发表于 2011-11-30 11:37


没记完, 就记得这么些, 这个应该是 05 年左右对 STL 源码狂感兴趣的时候看源码看到的, 就算在当时, 似乎也只有一个感觉, 这玩意真他妈罗嗦

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
47 [报告]
发表于 2011-11-30 11:47 |只看该作者
回复 43# zylthinking

>> 不是必然矛盾的, struct 的 {.mem = value} 语法, 我觉得就是一个例子。
那 constexpr 呢? auto 呢?  我觉得这也都是改动非常小, 又容易理解, 作用有很大的例子。
复杂的例子也有, 但很多时候真的是没有办法啊……

>> 要我自己琢磨一个例子, 我倒是想把 construct 做一个修改, 让他带返回值; 如果返回 -1, 则编译器自动 free 内存, 然后让new 返回NULL那么:
你与koolcoy关于异常的讨论我还没看。 这里先提一句……
new T(arg...)   如果分配内存成功, 但构造失败 —— 抛出了异常 —— 内存是会被回收的, 只要有配对的delete就行。
嗯。。。 又是你讨厌的那个异常…………

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
48 [报告]
发表于 2011-11-30 12:07 |只看该作者
回复 36# zylthinking

>> 现在为了避免 bad_alloc 异常, 又不想用 new (std::nothrow), 我基本上是 p = malloc(); if(p) new(p) XXX 这样写代码的
嗯…… if (p) ...  那else呢?  你打算怎么处理?

关于你说的丢失上下文, 确实会丢失, 因为C++设计的时候选择的是终结语意而非恢复语意。
异常一旦抛出, 就再也不会回到抛出时的状态。
相对的恢复语意, 比如Windows那个SEH, 就有提供恢复语意。 异常发生后往上查找, 某个handler可以选择进行一些处理, 然后回到异常发生地点继续执行。

BS在D&E里面关于这个选择列举了一大堆理由。
也说了一种模拟恢复语言的方式, 比如 std::set_newhander。
本质就是错误发生后不要理解抛出……  尝试,用newhandler恢复……  恢复不了再抛出。
其实并不怎么好用……  包括SEH的恢复也不怎么好用……

很多时候都不是选择恢复, 而是干脆重来一次……


而丢失的上下文…………  这个问题是被注意到了的…… 比如这个boost exception
不过这样就不仅仅在需要处理错误的地方用 try catch ……  还要在需要记录上下文的地方也用 try 然后在 catch 里面记录并 rethrow ……

如果用错误代码, 而且也打算记录丢失的上下文, 你打算怎么做呢…………

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
49 [报告]
发表于 2011-11-30 12:10 |只看该作者
本帖最后由 zylthinking 于 2011-11-30 12:14 编辑
回复  zylthinking

嗯…… if (p) ...  那else呢?  你打算怎么处理
如果用错误代码, 而且也打算记录丢失的上下文, 你打算怎么做呢
OwnWaterloo 发表于 2011-11-30 12:07


这个是程序业务逻辑啊, 该怎么处理合适怎么处理, 但离开这个上下文后, 一旦丢失信息, 你还真不知道怎么处理了
用错误代码, 本身就在上下文里面, 至少第一现场在上下文里面, 处理或不处理取决于程序员想干什么, 而 try catch 一旦也想这么干, 那么就失去了随意向上冒泡的自由

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
50 [报告]
发表于 2011-11-30 12:14 |只看该作者
回复 49# zylthinking

>> 这个是程序业务逻辑啊, 该怎么处理合适怎么处理, 但离开这个上下文后, 一旦丢失信息, 你还真不知道怎么处理了
举几个例子呗, 可能会有哪些处理方式。
以及如果想要保留上下文, 错误代码的方式应该怎么保留?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP