C++——string类和标准模板库

一、string类

  1、构造函数

  string实际上是basic_string<char>的一个typedef,同时省略了与内存管理相关的参数。size_type是一个依赖于实现的整型,是在string中定义的。string类将string::npos定义为字符串的最大长度,通常为unsigned int的最大值。另外,使用缩写NBTS(null-terminated string)来表示以空字符结束的字符串——传统的C字符串。下面的表格中列出了string的构造函数:

构造函数 描述
string(const char * s) 将string对象初始化为s指向的NBTS
string(size_type n, char c) 创建一个包含n个元素的string对象,其中每个元素都被初始化为字符c
string(const string & str) 将一个string对象初始化为string对象str(复制构造函数)
string() 创建一个默认的string对象,长度为0(默认构造函数)
string(const char * s,size_type n) 将string对象初始化为s指向的NBTS的前n个字符,即使超过了NBTS结尾

template<class Iter>

string(Iter begin,Iter end)

将string对象初始化为区间[begin,end)内的字符,其中begin和end的行为就像指针,用于指定位置,范围包括begin在内,但不包括end
string(const string & str, size_type pos = 0,size_type n = npos) 将一个string对象初始化为对象str中从位置pos开始到结尾的字符,或从位置pos开始的n个字符
string(string && str)noexcept 这是C++11新增的,他将一个string对象初始化为string对象str,并可能修改str(移动构造函数)
string(initializer_list<char> il) 这是C++11新增的,它将一个string对象初始化为初始化列表il中的字符

2、string类输入

  对于类,需要知道有哪些输入方式可用。对于C风格字符串,有3种方式:
    char info[100];

    cin >> info;//读取一个词

    cin.getline(info,100);//读取一行,遇到\n结束,并丢弃\n

    cin.get(info, 100);//读取一行,遇到\n结束,将\n丢弃在输入队列中

  对于string对象,有两种方式:

    string stuff;

    cin >> stuff;//读取一个词

    getline(cin,stuff);//读取一行,遇到\n结束并丢弃\n

二、智能指针模板类

  智能指针是行为类似于指针的类对象。

  auto_ptr是C++98提供的解决方案,C++11已将其摒弃,并提供了另外两种解决方案。然而,虽然auto_ptr被摒弃,但它已经使用了多年;同时,如果编译器不支持其他两种解决方案,auto_ptr将是唯一的解决方案。

  2.1、使用智能指针

  auto_ptr、unique_ptr和shared_ptr这三个智能指针模板都定义了类似指针的对象,可以将new获得(直接或间接)的地址赋给这种对象。当智能指针过期,其析构函数将使用delete来释放内存。因此,如果将new返回的地址赋给这些对象,将无需记住稍后释放这些内存:在智能指针过期时,这些能存将自动被释放。

  要创建智能指针对象,必须包含头文件memory,该文件模板定义。然后使用通常的模板语法来实例化所需类型的指针。例如,模板auto_ptr包含如下构造函数:

    template<class X> class auto_ptr{

    public:

      explicit auto_ptr(X *p = 0) throw();

    ...};

  throw()意味着构造函数不会引发异常;与auto_ptr一样,throw()也被摒弃。因此,请求X类型的auto_ptr将获得一个指向X类型的auto_ptr:

    auto_ptr<double> pd(new double);

    auto_ptr<string> ps(new string);

  new double是new返回的指针,指向新分配的内存块。它是构造函数auto_ptr<double>的参数,即对应于原型中参数p的实参。同样,new string也是构造函数的实参。其他两种智能指针使用同样的语法:
    unique_ptr<double> pdu(new double);

    shared_ptr<string> pss(new string);

  智能指针模板位于名称空间std中。下面的程序演示了如何使用全部三种智能指针。每个智能指针都放在同一个代码块内,这样离开代码的时候,指针将过期。Report类使用方法报告对象的创建和销毁。

 1 #include <iostream>
 2 #include <memory>
 3
 4 class Report{
 5 private:
 6     std::string str;
 7 public:
 8     Report(const std::string & s):str(s){
 9         std::cout << "创建了对象" << str <<"! \n";
10     }
11     ~Report(){
12         std::cout << "销毁了对象" << str << "! \n";
13     }
14     void comment()const{
15         std::cout << str << "\n";
16     }
17 };
18
19 int main(int argc, char * argv[])
20 {
21     using namespace std;
22     {
23         auto_ptr<Report> ps(new Report("using auto_ptr"));
24         ps->comment();
25     }
26     {
27         shared_ptr<Report> ps(new Report("using shared_ptr"));
28         ps->comment();
29     }
30     {
31         unique_ptr<Report> ps(new Report("using unique_ptr"));
32         ps->comment();
33     }
34     return 0;
35 }
36
37 输出结果:
38 创建了对象using auto_ptr!
39 using auto_ptr
40 销毁了对象using auto_ptr!
41 创建了对象using shared_ptr!
42 using shared_ptr
43 销毁了对象using shared_ptr!
44 创建了对象using unique_ptr!
45 using unique_ptr
46 销毁了对象using unique_ptr! 

  所有智能指针都有一个explicit构造函数,该构造函数将指针作为参数。因此不需要自动将指针转换为智能指针对象。

  由于智能指针模板定义方式,智能指针对象的很多方面都类似于常规指针。

  2.2、有关智能指针的注意事项

  为何使用三种智能指针呢?实际上有4种,另外一种是weak_ptr,但我们不讨论它。为何摒弃auto_ptr呢?

  先来看下面的复制语句:

    std::auto_ptr<std::string> ps(new std::string("Good morning!"));

    std::auto_ptr<std::string> vocation;

    vocation = ps;

  上述赋值语句将完成什么工作呢?如果ps和vocation是常规指针,则两个指针将指向同一个string对象。这是不能接受的,因为程序将视图删除同一个对象两次——一次是ps过期时,另一次是vocation过期时。要避免这种问题,方法有多种。

    *定义赋值运算符,使之执行深度复制。这样两个指针将指向不同的对象,其中的一个对象是另一个对象的副本。

    *建立所有权(ownership)概念,对于特定的值,只能有一个智能指针可拥有它,这样只有拥有对象的智能指针的析构函数会删除该对象。然后,让赋值操作转让所有权。这就是用于auto_ptr和unique_ptr的策略,但unique_ptr的策略更严格。

    *创建智能更高的指针,跟踪引用特定对象的智能指针数。这称为引用计数(reference counting)。例如,赋值时,计数将加1,而指针过期时,计数将减1 。仅当最后一个指针过期时,才调用delete。这是shared_ptr采用的策略。

  当然同样的策略也适用于复制构造函数。

  每种方法都有用途。下面的程序清单是一个不适合auto_ptr的示例:

#include <iostream>
#include <memory>
#include <string>

int main(int argc, char * argv[])
{
    using namespace std;
    auto_ptr<string> films[5] = {
        auto_ptr<string> (new string("卡卡西")),
        auto_ptr<string> (new string("佐助")),
        auto_ptr<string> (new string("宇智波鼬")),
        auto_ptr<string> (new string("凯")),
        auto_ptr<string> (new string("宁次"))
    };
    auto_ptr<string> pwin;
    pwin = films[2];

    for (int i = 0; i < 5; i++) {
        cout << *films[i] << endl;
    }
    cout << *pwin << endl;
    cin.get();
    return 0;
}

输出结果:
卡卡西
佐助
(lldb)  //程序崩溃了

  程序崩溃的原因在于,下面的语句将所有权从film[2]转让给pwin:

    pwin = films[2]; //films[2]丢失所有权

  这导致films[2]不再引用该字符串。在auto_ptr放弃对象的所有权后,便可能使用它来反问该对象。当程序打印films[2]指向的字符串时,却发现这是一个空指针。

  如果在上面的程序清单中用shared_ptr代替auto_ptr,则程序运行正常:

 1 #include <iostream>
 2 #include <memory>
 3 #include <string>
 4
 5 int main(int argc, char * argv[])
 6 {
 7     using namespace std;
 8     shared_ptr<string> films[5] = {
 9         auto_ptr<string> (new string("卡卡西")),
10         auto_ptr<string> (new string("佐助")),
11         auto_ptr<string> (new string("宇智波鼬")),
12         auto_ptr<string> (new string("凯")),
13         auto_ptr<string> (new string("宁次"))
14     };
15     shared_ptr<string> pwin;
16     pwin = films[2];
17
18     for (int i = 0; i < 5; i++) {
19         cout << *films[i] << endl;
20     }
21     cout << *pwin << endl;
22     cin.get();
23     return 0;
24 }
25
26 输出结果:
27 卡卡西
28 佐助
29 宇智波鼬
30 凯
31 宁次
32 宇智波鼬

  这次pwin和films[2]指向同一个对象,而引用计数从1增加到2 。在程序末尾,后声明的pwin首先调用其析构函数,该析构函数将引用计数降低到1 。然后,shared_ptr数组的成员被释放,对films[2]调用析构函数时,将引用计数降低到0,并释放以前分配的空间。

  unique_ptr与auto_ptr一样,也采用所有权模型。但使用unique_ptr时,程序不会等到运行阶段崩溃,而在编译阶段出现错误。

 

  

时间: 2024-10-07 08:56:29

C++——string类和标准模板库的相关文章

C++ Primer Plus 第六版 第16章 string类和标准模板库

1.string实际上是模板具体化basic_string<char> 的一个typedef,有默认参数,所以省略了初始化参数 2.size_type是一个依赖于实现的整形 string将string::npos定义为字符串的最大长度 3.string类的构造函数P656 4.对于c-风格字符串,3种输入方法:cin>>   cin.getline(),cin.get 对于string   ,2种输入方法:cin>>,getline(cin,string对象) 5.st

C++ primer plus读书笔记——第16章 string类和标准模板库

第16章 string类和标准模板库 1. string容易被忽略的构造函数: string(size_type n, char c)长度为n,每个字母都为c string(const string & str, size_type pos = 0, size_type n = pos)初始化为str中从pos开始到结尾的字符,或从pos开始的n个字符 string(const char *s, size_type n)初始化为s指向的前n个字符,即使超过了s的结尾: string(Iter b

《C++ Primer Plus》第16章 string类和标准模板库 学习笔记

C++提供了一组功能强大的库,这些库提供了很多常见编程问题的解决方案以及简化其他问题的工具string类为将字符串作为对象来处理提供了一种方便的方法.string类提供了自动内存管理动能以及众多处理字符串的方法和函数.例如,这些方法和函数让您能够合并字符串.将一个字符串插入到另一个字符串中.反转字符串.在字符串中搜索字符或姊姊富川以及执行输入和输出操作.诸如auto_ptr以及C++11新增的shared_ptr和unique_ptr等智能指针模板使得管理由new分配的内存更容易.如果使用这些智

9. string 类和标准模板库

目录 9.1 string 类 9.1.1 string 类的构造函数 9.1.2 string 类输入 9.1.2.1 string 类输入方法 9.1.2.2 string 类输入详解 9.1.2.3 使用 string 类 9.1.2.4 string 类的其他功能 9.2 智能指针模板类 9.2.1 使用智能指针 9.2 模板类 vector 9.2.1 使用 vector 类 9.2.2 可以对 vector 进行的其他操作 9.1 string 类 9.1.1 string 类的构造

C++标准模板库Stand Template Library(STL)简介与STL string类

参考<21天学通C++>第15和16章节,在对宏和模板学习之后,开启对C++实现的标准模板类STL进行简介,同时介绍简单的string类.虽然前面对于vector.deque.list等进行过学习和总结,但并没有一个宏观上的把握,现在通过上一篇和这一篇博文,将对C++模板以及基于C++模板的STL关联起来,形成一个总体的把握,对于掌握C++中模板(template)这一强有力的工具会十分有帮助.本文的主要内容有: (1) STL容器: (2) STL迭代器: (3) STL算法: (4) ST

C++标准模板库集合类与映射类总结

一.STL集合类 标准模板库向程序员提供了一些容器类,以便在应用程序中频繁而快速的搜索.std::set和std::multiset用于存储一组经过排序的元素,其查找元素的复杂度为对数,而unordered集合的插入和查找时间是固定的. 容器set和multiset快速查找键,键是存储在一维容器中的值,multiset可存储重复的键值,而set不行.STL容器是泛型模板类,可用于存储字符串.整型.结构或对象. 为了实现快速搜索,STL set和multiset内部结构类似二叉树,将元素插入到se

C++ Primer(第五版)学习笔记_5_标准模板库string(2)

C++ Primer(第五版)学习笔记_5_标准模板库string(2) 10.搜索string对象的元素或子串 采用find()方法可查找字符串中的第一个字符元素(char, 用单引号界定)或者子串(用双引号界定):如果查到,则返回下标值(从0开始计数),如果查不到,则返回一个很大的数string:npos(即:4294967295). #include <iostream> #include <stdio.h> #include <string> using nam

C++ Primer(第五版)学习笔记_4_标准模板库string(1)

C++ Primer(第五版)学习笔记_4_标准模板库string(1) 1.创建string对象 创建一个空字符串,其长度为0 #include <iostream> #include <string> using namespace std; int main(int argc, char* argv[]) { string s; cout << s.length() << endl; return 0; } 运行结果: 0 2.给string对象赋值

标准模板库

-------------------siwuxie095 在长期的编码中,聪明的程序员们发现:有一些代码经常碰到, 而且需求特别稳定,于是,各大公司在出售自己的 IDE 环境时, 就会把这些模板代码打包,一起销售 慢慢地,这些大公司之间就达成了某种共识,觉得应该把这些 涉及模板的通用代码进一步的统一和规范,于是,大家慢慢形 成了一套 C++ 的标准模板,就是现在所看到的标准模板库 标准模板库 标准模板库,即 Standard Template Lib,简称为 STL 标准模板库所涉及的内容非常