免费注册 查看新帖 |

Chinaunix

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

问一个有关于c++ vector的问题 [复制链接]

论坛徽章:
0
31 [报告]
发表于 2012-04-19 13:58 |只看该作者
回复 16# hgrany


本质上来说, move ctor就是旧的放弃所有权,新的获得

一般这里必然有个资源转移,说白就是拷贝。move是对返回优化的一个标准加强,而返回优化依赖编译器实现。
让返回必须调用拷贝构造函数变成了调用转移构造,并且不调用临时对象的析构,而之前是必须会被析构,这里就必须去完全的复制拷贝,所以是一个语言级别的bug。move来修正这个。我的描述不清晰你可以去看标准给的表达。

但很多时候事情并不都是那么完美. 这里所说的设计良好,限制还是挺多的

显然是这样,凡事哪有说得那么简单。说的好听,做起来,那还是有些苦头。

那些老代码自然不可能有move ctor了. 这种情况下给新类加move ctor是没有意义的

move语义是给新代码的礼物,也为了让老代码,你说的没有move拷贝那些代码能兼容使用。这没什么问题,库一般会慢慢支持起来,因为move换来的效率还是可观的,关键是他修正了一个bug。我现在更关心的是各个编译器能快些达成一致,把标准完整实现了,这样我才敢用。c++11实现好了,是不是kde桌面会快一些?那个时候gnome咋办

你不可能push_back 一个派生类的实例到存储基类对象的vector中去

为什么不能?这里有个切片。我非要存为什么不可能,尽管这是一个普遍错误的做法。
可能是可能,只是不该这么做。

论坛徽章:
0
32 [报告]
发表于 2012-04-19 13:59 |只看该作者
回复 19# redpigcool


居然有人说stl是大库。唉

论坛徽章:
0
33 [报告]
发表于 2012-04-19 14:02 |只看该作者
回复 24# 幻の上帝


你没理解我的意思。

reserve了直接[]访问,这个不会触发例外。用完了resize一下。

当然,也可以直接resize一下,然后[]访问填充,但是你得提前知道要填充多少个。

resize里面应该也就是先reserve了再来设置大小。我只是担心我前面跟你说的,resize是不是依然会重新拷贝。讨论这个没意义。

论坛徽章:
0
34 [报告]
发表于 2012-04-19 22:24 |只看该作者
回复 33# walleeee

resize()对于构造/析构开销大的对象,性能损失可能无法忽视。
全reserve()用[]访问倒不是不可以。但有个不方便的地方就是得时刻提防着不手贱。
1.超过size()的部分必须先写再读,否则UB。
2.不确认用完不resize()。
3.不push_back()之类。
照你的手法倒是可以都符合。

论坛徽章:
0
35 [报告]
发表于 2012-04-19 22:32 |只看该作者
本帖最后由 幻の上帝 于 2012-04-19 22:34 编辑

回复 27# walleeee

动态数组应该叫什么我倒是无所谓。不过C/C++的array和传统意义上的array有相当大的区别,简单叫array说不过去。而C++11也有array了,和内建array类似,大小是编译时确定的。
得再加一层指针按你的方式理解大概是相当极端的情况了:构造函数塞了一大堆不像内存那么容易拿到的资源申请。这种风格的好坏不论,可以肯定的是实际有可能用。
上面说的“频率少”是有点不太对,实际的性能瓶颈确认起来当然没那么简单。


论坛徽章:
0
36 [报告]
发表于 2012-04-19 22:37 |只看该作者
回复 34# 幻の上帝



就这一个就让人觉得python等众舒心。效率?狗屁。

论坛徽章:
0
37 [报告]
发表于 2012-04-19 22:42 |只看该作者
回复 35# 幻の上帝


构造函数只把对象初始化到一个无效状态,比如char*置nullptr。而不要分配任何可能失败的资源。
这是原则,任何其他原则都不能破坏这个原则。

实际的性能瓶颈确认起来当然没那么简单

当然。这需要一些经验,甚至要靠运气,猜测和实验。不过也有一些做这个事情的工具。

论坛徽章:
0
38 [报告]
发表于 2012-04-20 11:49 |只看该作者
回复 37# walleeee


恩,谢谢。我也是这么想的,既然不能控制调用构造的时机,尽量把构造函数的开销降到最低,然后根据需要初始化。

论坛徽章:
0
39 [报告]
发表于 2012-04-20 15:08 |只看该作者
回复 38# redpigcool


这个原则,之所以这样做,并非为了你说的效率那么简单。事情很复杂,你多实验,大可以用你现在觉得正确的方式来搞,搞多了就会有想法。

论坛徽章:
0
40 [报告]
发表于 2012-04-20 19:09 |只看该作者
回复 37# walleeee

很遗憾,现实是构造函数仅表示对象生存期即将开始,并没有断言这个对象之后行为的丰富含义。
所以一些构造函数扮演重要角色的惯用法,如RAII、scope guard,就拒绝这种假设——额外的、不必要的对代码可靠性的依赖。
当然你可以约定这么做(顺便可以多加点限制,像构造函数禁止抛出异常等等),但既然没有任何规则保证这个限制总是成立,语言也没有提供检查违反这种约束的能力,你不得人肉检查所有还没有取得你信任的代码,或者干脆不使用这些代码。
于我而言,我拿不出精力集中于此,或者说宁可把这方面精力放在使程序更通用上(因为这不仅能解决这一个问题)。

可能根本的关键点在于,你认为对象应该只是状态的抽象,而我认为不仅如此——语言的规则限定了的既成事实就是这样(虽然我也不满这点:http://bbs.chinaunix.net/thread-3607796-9-1.html,88L)。

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP