跨平台字符串类实现良好的模型可移植性"Best Practices"是什么?
What are "Best Practices" for a Cross-Platform string class to implement good model portability?
关于跨平台Unicode字符串使用的主题有无数的讨论线程,但似乎有广泛的意见,没有解决一些特定的问题,这些问题一直困扰着我在一个特定的项目中工作:
我有一个很大的跨平台c++代码库,可以追溯到近20年前。它包含了各种类型的字符串实现,包括:
-
char*
- Pascal-style字符串
-
std::string
- 具有重叠功能的多个自定义跨平台类
-
CFString
- 各种类型的常量字符串
这个代码库正在被重写,以完全使用Unicode字符串和实现一个强大的MVC架构,希望模型将是完全可移植的(Mac OS/IOS/Android/Windows 7 &8/Unix).
当持久数据被写入XML/UTF-8时,在运行时对象中使用字符串存在一些困境:
-
我想创建一个类,干净地隐藏存储,分配和常见的字符串操作的实现。通过c++操作符和赋值重载的奇迹,我希望能够替换一个类实例来替换函数可以接受的所有不同的字符串参数。这将允许代码库的增量转换。
-
我们不断地扫描/解析/分析字符串,我担心对持久对象使用严格的UTF-8底层实现可能会有性能问题。如果不是,在微软的vc++和GNU的g++中发现的现代std::string是不是一个简单的底层实现?
-
Mac OS/IOS版本最终需要将它们的字符串"转换"为CFString。CF函数丰富且高度优化。我认为这将是一个很好的策略,让我自己的类通过提供CF与缓冲区创建CFStrings(例如,
CFStringCreateWithCharactersNoCopy
或CFStringCreateMutableWithExternalCharactersNoCopy
)。似乎这可以减少转换/分配CFString通常需要从模型中获取数据后的数量-虽然也许在一个适当的MVC实现控制器/视图不应该访问模型拥有的实际字符串? -
c++ 11是否改变了这些跨平台字符串问题的情况?
我本以为这些问题早就应该解决了——但是从这个网站(和其他网站)上的回复来看,我看不出有什么问题。
我想创建一个类,干净地隐藏存储,分配和常见的字符串操作的实现。通过c++操作符和赋值重载的奇迹,我希望能够替换一个类实例来替换函数可以接受的所有不同的字符串参数。这将允许代码库的增量转换。
听起来像std::string
,添加了对const char*
的强制转换操作符,所以您不必调用c_str()
。这就意味着你必须使用char
和UTF-8来存储,而不是使用UTF-16或类似的格式。
我们不断地扫描/解析/分析字符串,我担心对持久对象使用严格的UTF-8底层实现可能会有性能问题。如果不是,在微软的vc++和GNU的g++中发现的现代
std::string
会是一个简单的底层实现吗?
这取决于其他几个因素。一方面,如果输入包含大量非ascii数据,并且必须一次分析一个代码点,那么UTF-8 可能会效率低下。在这种情况下,UTF-16甚至UTF-32可能更合理,因为您不会有太多的大小写差异来重新组装来自多个字符串元素的代码点。另一方面,性能在很大程度上取决于您是可以通过引用传递字符串还是必须创建副本,特别是在调用函数时。因此,为了避免过多的副本,对现有代码库进行一些修改可能是必要的。
Mac OS/IOS版本最终需要将其字符串"转换"为CFString。CF函数丰富且高度优化。我认为这将是一个很好的策略,让我自己的类通过提供CF与缓冲区创建CFStrings(例如,CFStringCreateWithCharactersNoCopy或CFStringCreateMutableWithExternalCharactersNoCopy)。似乎这可以减少转换/分配CFString通常需要从模型中获取数据后的数量-虽然也许在一个适当的MVC实现控制器/视图不应该访问模型拥有的实际字符串?
当您创建字符串而不复制数据缓冲区时,那么您必须确保只要字符串被访问,缓冲区就存在。这在某些情况下可能是正确的,但并非所有情况都是如此。一般来说,这些问题与由std::string
支持的char*
非常相似,这就是为什么c_str()
是显式函数调用而不仅仅是自动强制转换的原因。通过进行这样的转换,必须保证原始对象保持已分配状态。一般来说,我会将const std::string&
传递给视图,这样它们就不会意外地改变模型拥有的字符串。如果他们需要保留或修改字符串,他们必须复制它。
c++ 11是否改变了这些跨平台字符串问题的图景?
c++ 11提供了许多新的智能指针实现,允许你更好地控制字符串对象的分配时间。因此,例如,您可以使用shared_prt<string>
作为类的数据存储,以获得自动引用计数和字符串的释放。这将为您提供更高层次的抽象,但可能与您当前的代码库所做的工作相去甚远,因此我不确定这是否会使移植更容易。
- C++Union/Struct位域的实现和可移植性
- 静态库可移植性
- C++:Unicode 字符串文字的可移植性
- 如何使Visual Studio 2017 C++项目在计算机之间更具可移植性
- 在为视频游戏实施基本的二进制序列化时,请担心可移植性
- 重写类以使其更通用,以实现可移植性
- Visual Studio 2015 <=> QtCreator 5 (c++) 代码可移植性
- 通过虚拟接口类导出C 类的可移植性
- 位移位可移植性
- 如何在Visual Studio中进行串行端口编程C++Windows和Linux之间的可移植性?
- 提高 Python 可移植性问题
- 库如何在不同的操作系统之间实现可移植性
- 使用C 11 /最近的G 版本(4.7 / 4.6)的可移植性
- 模板函数实例化的可移植性问题
- XCode、命名空间、C++和代码可移植性
- 嵌入式C++项目 - 需要支持智能指针.可能的可移植性问题
- 使用指针遍历数组的可移植性
- 头文件中内联自由函数的可移植性
- 文件IO中的可移植性问题
- 跨平台字符串类实现良好的模型可移植性"Best Practices"是什么?