
2.1.5 C++中的字符串
在C++程序中,多字节字符串和宽字符串都是常见的数据类型,但人们也已做出许多努力来创建字符串类。大多数C++开发人员都至少写过一个字符串类,并且字符串类有许多被广泛接受的形式。C++的标准化[ISO/IEC 1998]促进了标准的类模板std::basic_string的规定。该basic_string模板代表一个字符序列。它支持序列存取操作也支持字符串操作(如搜索和串连),并且是由字符类型参数化的:
·string是模板特化basic_string的一个typedef。
·wstring是模板特化basic_string的一个typedef。
因为C++标准定义了额外的字符串类型,所以对于多字节字符串,C++还定义了额外的形式。一个以空字符结尾的字节字符串也称为NTBS(Null-Terminated Byte String),它是一个字符序列,最高地址的元素定义的内容具有值0(即终止空字符),序列中的其他元素都不具有值0。一个以空字符结尾的多字节字符串也称为NTMBS(Null-Terminated Multibyte String),它是一种NTBS,构成了一个以初始转换状态开始和结束的有效多字节字符序列。
与以空字节结尾的字符串相比,basic_string的类的模板特化更不容易出现错误和安全漏洞。遗憾的是,在C++字符串对象和以空字符结尾的字节字符串之间有一个错配。具体来说,大多数C++字符串对象都被视为不可分割的整体(通常按值传递或按引用传递),而现有的C库函数都接受指向以空字符结尾的字符序列的指针。在标准C++的string类中,其内部表示并不一定非得是以空字符结尾的[Stroustrup 1997],虽然所有常见的实现都是以空字符结尾的。其他一些字符串类型,(例如,Win32 LSA_UNICODE_STRING),也不一定非得是以空字符结尾的。因此,访问字符串的内容、确定字符串长度,以及判断一个字符串是否为空有不同的方式。
在C++程序中几乎不可能避免使用多种字符串类型。如果你想独占地使用basic_string,你必须确保,目前并无任何下列情况。
·basic_string的字面值。一个如"abc"的字符串字面量是一个以空字符结尾的静态字符串。
·与接受以空字符结尾的字节字符串现有库的交互(例如,在中声明的函数签名操纵的许多对象是NTBS)。
·与接受以空字符结尾的宽字符串现有库的交互,(例如,在中声明的函数签名操纵的许多对象是宽字符的序列)。
通常情况下,C++程序使用以空字符结尾的字节字符串以及一个string类,虽然在一个遗留代码库里往往有必要处理多种字符串类[Wilson 2003]。