huaxiazhihuo

 

string类的设计

String类的设计一点都不容易,先不论C++,那怕是其他语言,在面对string的时候,一不小心也会掉坑,好比java,好比C#,一开始假设utf16是定长编码,后来Unicode发展到两个字节就装不下一个码位,字符串在java下,就有点尴尬了。就算是昧着良心用utf32编码,码元与码位终于一一对应了,也会遇到物理字符与逻辑字符不对应的时候,好像有些语言的字符要用两个unicode值来表示(很奇怪),有些语言的一个小写字符对应着好几个大写字符。即便是字符串选定了一种编码方式,始终还是要解决与其他编码的交互问题,这些交互接口也不容易设计。另外,每次从长字符串中截取字符串都要重新new出来一条新的字符串,难免有一点点浪费,当然,现在计算机性能过剩,这纯粹是强迫症。

而到了c++下,设计字符串所遇到的问题,就远比想象中复杂,无中生有的又凭空多出来很多不必要的要求,内存资源管理(这个在C++几乎是无解),异常安全(往字符串添加新内容,假如内存分配失败,必须保持原有值的完整性),还有性能要求(截取字符串避免生成新的字符串)。很多很多的要求,导致语言层面上压根就没法也不可能提供原生的字符串支持,而这一点上又引出来新的问题,代码里面,逻辑意义上看,就不止存在一种字符串类型。好在,大C++拥有丰富多彩的feature,应该足以实现字符串类型了,这也是大C++的设计哲学,既然语言上没法实现的东西,就提供用以支持这种东西的feature,用户要怎么实现就怎么实现,选择权交到用户手里。

所以,C++的库要怎么做出来一道string,这道菜的味道如何,就很让人好奇。一路考察下来,让人大跌眼镜,竟然没有一个c++库能提供品质优良字符串, 其抽象充其量也就是比字符数组好一点点,完全就没有Unicode编码的抽象。Stl的字符串更让人发指,竟然有几个模板参数,本来多类型的字符串问题就更是雪上加霜了,另外stlstring还不能作为dll函数的参数类型。其实,很多时候,猿猴的要求真的不高,只要求一种utf8编码的string,带有格式化,还有一些splittrimFindOneOftoupper等常用字符串处理的操作就行了,只可惜,没有一个c++库能基本满足这样的基本要求。其实,这些要求,具体到C++下,要基本满足,也的确很困难。

除了c++,很多语言的string类型都是原子属性,一个string值,但凡一点风吹草动,都要生成新的string值,原有的值必须保持不变。此外,其官方也提供了类似于StringBuffer或者StringBuilder用以构造很长很长,以弥补这种动不动就生成新String的性能问题。这两种类型泾渭分明。而c++string,似乎是把这两种类型糅合在一块了,由此带来语义上的不清晰,也造成很多不必要的麻烦,因为绝大多数场合下,只需要使用string的原子属性,可变的string只是用来保存字符缓冲而已。知道吗,stlstring有一百多个成员函数,很多都是不必要的重载,不过是为了避免字符串的复制而已。

所以,首先要对只读的string做抽象,也即是string_view,只需两个成员字段,字符串的起始地址以及缓冲长度,并且不要求以0结束,它有一个很好的特性,字符串的任何一部分,也都是字符串,甚至,必要时,一个字符,通过取地址,也可以看做是长度为1string_view。任何连续的内存字符块,都可以看做是string_view。其不必涉及内存的分配,显得非常的轻量级,可以在程序中到处使用,只需注意到字符缓冲的生命周期,就不必担心会引来什么问题。在string_view上,可以做trim,比较,查找,反向查找等操作,除了读取单个字节的迭代器,还提供两套迭代器,用以取到unicode码位值(uin32),和用以访问逻辑字符,其值也为stirng_view

剩下来就是可写可修改的string,要求以0结束,也即是stlstring,因为很多函数都在string_view上,所以这里基本上都只是插入、添加、删除、替换的操作,要注意的是,中括号操作符不能返回字符引用,因为那样完全没有任何意义,就算是保留中括号返回字符值,意义也很小。Trim、查找、比较等操作,必须通过其成员函数view来返回代表自己的string_viewString的很多成员函数,大多数参数类型就是string_view,因此也没有像是在stl下垃圾string的那么多乱七八糟的重载。很简明的设计,性能与简单的良好统一,不知为何,stl要到c++17的时候,才会加入stirng_view这么重要的类型,即便是如此,stlstring既有代码已成定局,也没办法用string_view来简化它的一百多个的成员函数了

posted on 2018-05-26 11:51 华夏之火 阅读(1312) 评论(0)  编辑 收藏 引用 所属分类: c++技术探讨


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

常用链接

留言簿(6)

随笔分类

随笔档案

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜