目录

重学C++:标准库类型string


常见的坑

  1. string.size()string.length()等价。

    string.size()和其他STL容器的命名风格相一致(如vector, map)。

    string.length()出现主要是因为这样的命名符合人的直觉,有更好的可读性。

  2. string::size_type是无符号类型,和int不同,能存放下任何string对象的大小。

  3. +两边至少有一端需要是string对象,不允许两个字符串字面量单独相加。

    1
    2
    3
    4
    
    using std::string;
    string a = "a";
    string b = a + "b" + "c";   // 正确,从左到右运算时能保证至少一段是string对象
    string c = "b" + "c" + a;   // 错误,从左到右运算时第一个+左右都是字符串字面量
    

必须要理解的点

  1. string的初始化方式有两种,一种是默认初始化,另一种是拷贝初始化。

  2. string.size()返回值类型为string::size_type,出现这种类型是为了体现标准库类型和机器无关的特性。

  3. string对象的比较运算完全实现了运算符重载(==, !=, <,<=, >, >=)。

    ==表明两个对象的内容和长度完全一致,反之任一不同则!=

    不等关系运算符比较的法则:

    1. 如果两个对象长度不同,但是从前到后内容一致,则长度较短的对象较小。
    2. 如果两个对象从前到后有对应位置的字符不同,则这个位置的两个字符的大小关系就是两个对象的大小关系。
  4. string对象赋值操作就是内容的替换。

  5. string对象相加操作就是内容的拼接,+=操作同理。

  6. string对象可以与字符串字面量相加。

  7. 形如cnameC++头文件兼容形如ctype.hC头文件,C++头文件中定义的名字可以在std中找到。

建议

  1. 表达式中出现string.size()函数时就不应该使用int类型,这样可以避免intunsigned混用的问题。

  2. C++C兼容的头文件作选择时,选择C++的头文件。

  3. 处理string对象中每一个字符时,使用foreach语句。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    
    #include <iostream>
    #include <cctype>
    
    using std::string;
    
    string str{"Some String"};
    for (auto c : str) {
        std::cout << c << std::endl;
    }
    
    // 使用引用来改变原字符串内容
    for (auto &c : str) {
        c = std::toupper(c);
    }
    std::cout << str << std::endl;
    
  4. 处理string对象中特定字符时使用[](下标运算符)或者迭代器。

    使用[]访问字符之前检查string对象是否为空。

    1
    2
    3
    4
    
    std::string s = "a";
    if (!s.empty()) {
        std::cout << s[0] << std::endl;
    }
    
  5. string对象下标使用string::size_type作为类型而非int

    1
    2
    3
    4
    
    using std::string;
    
    string a = "Hello, world!";
    string::size_type index_of_space = a.find(" ");