免费注册 查看新帖 |

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
31 [报告]
发表于 2011-11-30 10:34 |只看该作者
本帖最后由 zylthinking 于 2011-11-30 10:41 编辑
你没领会到异常的精髓啊,异常的精髓在于什么时候不try/catch。如果你每个函数调用都try/catch还用异常 ...
koolcoy 发表于 2011-11-30 10:32



是没有领会到, 实在惭愧, 昨天又仔细琢磨了一下, 其实确实我没耐心研究模版及其lamda之类的, 以自己片面眼光武断评论, 还真是不可取。
不爽c++者, 其实应该是新增特性的复杂的语法, 而不是特性本身, 如果能有一种感觉和原有风格融为一体, 简洁明快的语法呈现, 说不定绝大部分本能拒绝这些特性的人反而会欢呼雀跃。

但异常现在的理解还是一种粗旷式的错误管理, 尽管 try catch 可以跨越层别的抓住异常, 但很显然也容易让错误失控, 或者说, 容易破坏代码的分层结构

论坛徽章:
0
32 [报告]
发表于 2011-11-30 10:41 |只看该作者
我感觉很不好接受,可能我只是用的少吧

论坛徽章:
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
33 [报告]
发表于 2011-11-30 10:46 |只看该作者
本帖最后由 zylthinking 于 2011-11-30 11:00 编辑
我需要一个类似 vector 的东西, 实现一个。 (这里我就不说类型了, C里面容器要类型无关也不算太麻烦 ...
OwnWaterloo 发表于 2011-11-30 02:56


这个各有理解了, 数据结构和算法我认为是分不开的。
所谓容器和算法的分离, 其实质不过是对容器又做了一层抽象, 约定了所有容器的公共接口。
为此, 所有容器都内嵌 iterator 类型, iterator 还分单向, 双向, 随机访问类型, 还分 iterator 与 const_iterator, 容器内部还有什么 type, ref_type, const_ref_type 等等, 基本上是为通用算法准备的.
由此导致的一个后果是, 如果你想自己写一个容器还能和他的算法配合, 那个容器你有的费力气了, 等写完了, 让别人来看看, 基本上看起来不容易懂
因此, 实现两者的分离不是天生很自然就是的了, 而是里面有着太多的苦力, 和AD0818那一个 mfor.h一样, 表面上风光无限, 看看内部, 无语得很
就是所谓STL排序, 如果 T 没有重载或是原生支持 <, 或者人为传进去一个 compare function object, 他还能适用吗?

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

>> 所谓容器和算法的分离, 其实质不过是对容器又做了一层抽象, 约定了所有容器的公共接口。
对, 实质就是这样, 约定了一个接口。

>> 就是所谓STL排序, 如果 T 没有重载或是原生支持 <, 或者人为传进去一个 compare function object, 他还能适用吗?
当然不行。
但这里留出一个接口,让排序的代码固定, 让排序自己决定不了的事 —— 如何规定大小 —— 不固定, 不正是为了让其他部分的代码被复用吗?

比如, 使用read/write 什么的代码, 是否与具体的文件类型分开了?
这些代码(指那些不需要具体文件提供的更高级功能的)可以与任何满足read/write接口的文件一起使用。
这种分离还是通过具体的文件类型与操作文件的代码之间约定了 read/write 这样的接口才能完成。

要连这样的约定都没有……   该怎么写……

只是template与read/write与virtual function的约定方式不一样。
template 主要是看, 比如 push_back(x), ++it 这样的表达式是否能编译通过。
而不管具体的函数签名是怎样的, 或者继承体系是怎样的。

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
35 [报告]
发表于 2011-11-30 10:59 |只看该作者
回复 31# zylthinking

>>但异常现在的理解还是一种粗旷式的错误管理, 尽管 try catch 可以跨越层别的抓住异常, 但很显然也容易让错误失控, 或者说, 容易破坏代码的分层结构
异常的确破坏了代码的分层结构,异常使得代码产生了顺序执行、循环执行和分支执行之外另外一种执行路径。

引入异常的设计目的是让把代码的逻辑处理部分和错误处理部分分开。举个例子:

  1. if ((fd = socket(...)) < 0) {
  2.         blar_1();
  3.         goto foo;
  4. }
  5. if ((fcntl(fd, ...)) < 0) {
  6.         blar_2();
  7.         goto foo;
  8. }
  9. if ((setsockopt(fd, ...)) < 0) {
  10.         blar_3();
  11.         goto foo;
  12. }
复制代码
上面这种所谓健壮的C代码随处可见,这种写法在有些时候是必须的,可以很明显地看到逻辑代码和错误处理代码搅在一起。
如果引入异常后就完全不一样了,在调用socket/fcntl/setsockopt的地方我可以不处理异常,我让异常一直往上抛,直到main(或者其它重要的地方)一起搞定所有的异常。这样就成功地把逻辑代码(调用socket/fcntl/setsockopt)和错误处理代码(main或者其它能处理异常的地方)分开了。

论坛徽章:
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
36 [报告]
发表于 2011-11-30 11:05 |只看该作者
本帖最后由 zylthinking 于 2011-11-30 11:07 编辑
回复  zylthinking

>>但异常现在的理解还是一种粗旷式的错误管理, 尽管 try catch 可以跨越层别的抓住 ...
koolcoy 发表于 2011-11-30 10:59


你说的是优点, 我说的是缺点, 综合起来是既有优点又有缺点。
每个人观点不一样, 我觉得这个优点不足以打动我让我用它, 异常是可以向上不断抛, 但每向上抛一层, 具体上下文信息或多或少的就要损失一些, 等抛到了main, 除了知道发生了异常外, 还能不能知道具体是什么错误, 该怎么处理这个错误, 如何重新进入那个具体的上下文重新执行, 恐怕都是问题

现在为了避免 bad_alloc 异常, 又不想用 new (std::nothrow), 我基本上是 p = malloc(); if(p) new(p) XXX 这样写代码的

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

>> 为此, 所有容器都内嵌 iterator 类型, iterator 还分单项, 双向, 随机访问类型, 容器内部还有什么 type, ref_type, const_ref_type 等等, 基本上是为通用算法准备的, 由此导致的一个后果是, 如果你想自己写一个容器还能和他的算法配合, 那个容器你有的费力气了

这个本质上也还是上面说的约定吧?
就像要增加一种文件类型, 就要提供 read/write/open/close/seek/tell/... 什么的, 其实也一大堆。
virtual function也一样, 也要实现一堆。
都不是轻松的事。


>> 因此, 实现两者的分离不是天生很自然就是的了, 而是里面有着太多的苦力, 和AD0818那一个 mfor.h一样, 表面上风光无限, 看看内部, 无语得很

这不一样啊。

宏是C语言一直都存在的东西, 但为什么就没被玩出template那样的花样? 就是因为宏不是图灵完备的嘛……
AD0818那个 mfor.h , 应该有一个可计算的上限。  其实根本不是在计算, 而是预先计算好了然后去匹配……


C++03的问题就是玩template的时候还有一些地方需要依赖宏……
比如产生一个参数列表……
专门有一个库, boost.pp, 就是为了解决这样一类的事情: 进行一些扩展, 产生类似下面的代码
typename P0, typename P1, typename P2, ...  不变的是typename 或者是 typename P, 后面的数字是展开次数。
或者P0 a0, P1 a1, ...
蛋疼得很……  而且依然不是在计算, 而是预先有一个上限值。

于是C++11引入了一个异常强大的variadic template……

论坛徽章:
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
38 [报告]
发表于 2011-11-30 11:14 |只看该作者
回复  zylthinking

>> 为此, 所有容器都内嵌 iterator 类型, iterator 还分单项, 双向, 随机访问类 ...
OwnWaterloo 发表于 2011-11-30 11:08


对本质还是约定, 但约定太多了就是麻烦了。

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
39 [报告]
发表于 2011-11-30 11:15 |只看该作者
回复 36# zylthinking

将错误码一级一级地往上返回跟异常一层一层地往上抛有啥区别? 如果一个函数能不往上返回错误码,那么换成异常后这个函数一定能把异常捕获并处理掉。一个错误码能携带的信息用异常完全可以携带。因此异常跟错误码没啥本质区别。异常慢一些、编写异常安全的代码难度高一些,仅此而已。

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

>> 不爽c++者, 其实应该是新增特性的复杂的语法, 而不是特性本身, 如果能有一种感觉和原有风格融为一体, 简洁明快的语法呈现, 说不定绝大部分本能拒绝这些特性的人反而会欢呼雀跃。

要想有新特性, 又能简洁明快……  这其实本来就是矛盾的……

比如K&R到C89到C99到C1x, 还有以简化为卖点的java, 从一开始到目前的java7? 都是越来越复杂的。
而且也都会被部分C程序员与java程序员抵制的……


提供新的机制, 但又不过多引入复杂性, 要靠语言的良心了……
我觉得C++已经算比较有良心的了, 改变语言很谨慎很谨慎。

没良心的, 我上面说的python, 那真是脑门一拍, 说改就改。
有良心的例子, 就是我上面说的lua, 给人的感觉就是对程序员提议的新的需求很有耐心, 除非我考虑完善了, 否则我就是不改。
不算标准库什么的, 就说语言本身, lua比python简单到哪去了……  但表达能力真不输python。
而且还可以感觉到这语言真的是在往这个方向努力, 尽力提供更泛用的概念与功能, 并将以前的概念尽力整合。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP