C++ Primer 笔记七

第十六章 string类和标准模板库

16.1 string

1.构造字符串(string的构造函数)

  

名称

说明

 

String(Char*) 

将 String 类的新实例初始化为由指向 Unicode 字符数组的指定指针指示的值。

 

String(array<Char>[]()[]) 

将 String 类的新实例初始化为由 Unicode 字符数组指示的值。

 

String(SByte*) 

将 String 类的新实例初始化为由指向 位有符号整数数组的指针指示的值。

 

String(Char, Int32) 

将 String 类的新实例初始化为由重复指定次数的指定 Unicode 字符指示的值。

 

String(Char*, Int32, Int32) 

初始化为由指向 Unicode 字符数组的指定指针、该数组内的起始字符位置和一个长度指示的值。

 

String(array<Char>[]()[], Int32, Int32) 

初始化为由 Unicode 字符数组、该数组内的起始字符位置和一个长度指示的值。

 

String(SByte*, Int32, Int32) 

初始化为由指向 位有符号整数数组的指定指针、该数组内的起始字符位置和一个长度指示的值。

 

String(SByte*, Int32, Int32, Encoding) 

初始化为由指向 位有符号整数数组的指定指针、该数组内的起始字符位置、长度以及 Encoding 对象指示的值。

2.string类输入

 

对于C风格字符串有三种方式

char info[100];

cin>>info;

cin.getline(info,100); //固定大小

cin.get(info,100);

对于string对象有两种方式。

string str;

cin>>str;

getline(cin,str); //可自动调节str大小

 

两个版本的getline()都有一个可选参数,制定使用那个自负来确定输入边界cin.getline(info,100,’;’); getline(cin,str,’;’);

string是个类,这是操作符重载,如:getline(cin,str);  operator>>(cin,str);

3.使用字符串

length()和size()成员函数都返回字符串中的字符数。

string::nops是字符串可存储的最大字符数,通常是无符号int或无符号long的最大取值

方法原型

描述

size_type find (const string &str, size_type pos=0) const

从字符串的pos位置开始查找子字符串str,如找到则返回子字符串首次出现时其首字符的索引,否则返回string::nops

size_type find (const char* s, size_type pos=0) const

从字符串的pos位置开始查找子字符串s,如找到则返回子字符串首次出现时其首字符的索引,否则返回string::nops

size_type find (const char* s, size_type pos=0,size_type n)

从字符串的pos位置开始查找子字符串s的前n个字符组成的子字符串,如找到则返回子字符串首次出现时其首字符的索引,否则返回string::nops

size_type find (char ch, size_type pos=0) const

从字符串的pos位置开始查找字符ch,如找到则返回字符ch首次出现时其首字符的索引,否则返回string::nops

string库还提供了相关方法,rfine()查找子字符串或字符最后出现的位置、find_first_of()在字符串中查找参数中任何一个字符首次出现的位置、find_last_of()在字符串中查找参数中任何一个字符最后依次出现的位置、find_first_not_of()在字符串中查找第一个不被包含在参数中的字符、find_last_not_of()字符串中查找最后一个不被包含在参数中的字符

string还提供了哪些功能

附录F

16.2 auto_ptr

auto_ptr是一个模板类,用于管理动态内存分配的用法。(头文件:memory

使用auto_ptr

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

template <class X> class auto_ptr{

public:

explicit auto_ptr (X* p = 0)throw();  // throw()表示构造函数不引发异常

….} //explicit表示构造函数是显式的,不支持隐式类型转换

将使用new的函数转换为使用auto_ptr的函数:1.包含头文件memory2.将指向string的指针替换成指向stringauto_ptr对象;3.删除delete语句。

auto_ptr <double> pd (new double); auto_ptr <string> pd (new string); auto_ptr <string> pd (new string(str));

new double 是new返回的指针,指向新分配的内存块。它是auto_ptr<double>构造函数的参数,即它是对应于原型中形参p的实参。

有关auto_ptr的注意事项

只能对new分配的内存使用auto_ptr对象,而不要对由new[]分配的,或通过声明变量分配的内存使用它。

auto_ptr <string> pd (new string(“It’s my bag.”));

auto_ptr <string> lily;

lily = pd;

两个指针将指向同一个string对象,其中一个是另一个的拷贝。上述赋值语句不可接受,因为当pslily都过期时,程序将试图删除同一个对象两次。

要避免这种问题可以有多种方法:

1.定义复制操作符,使之执行深复制。

2.建立所有权概念,对于特定的对象,只有一个智能指针可以拥有它。智能指针的构造函数只能删除该智能指针拥有的对象。并使复制操作转让所有权,这就是用于auto_ptr的策略。(但是如果所有权被转让,则前一个对象将不再引用该字符串。)

3.创建智能更高的指针,跟踪引用特定对象的智能指针数,这被成为引用计数,仅当最后一个指针过期时,delete才被调用。

16.3  STL

STL提供了一组表示容器、迭代器、函数对象和算法的模板。STL容器是同质的,即存储的值的类型相同;算法是完成特定任务的处方;迭代器是用来遍历容器的对象,与遍历数组的指针相似,是广义指针;函数对象是类似于函数的对象,可以是类对象或函数指针(包括函数名,因为函数名被用作指针)。STL不是面向对象的编程,而是一种不同的编程模式——通用编程技术。

vector模板类

分配器

string类相似,各种STL容器模板都接受一个可选的模板参数,该参数制定使用哪个分配器对象来管理内存。例如,vector模板的开头与下面的类似

template <class T, class Allocator = allocateor<T> >

class vector {…..

如果省略该模版参数的值,则容器模板将默认使用allocator<T>类,这个类以标准方式使用newdelete 

16.4通用编程技术

通用编程技术旨在编写独立于数据类型的代码。在C++中完成通用程序的工具是模板。

迭代器:是一个广义指针。事实上,它可以使指针,也可是是一个可以对其执行类似指针操作——如解除引用(*p)和递增(p++)——的对象。每个容器类都定义了一个合适的迭代器,该迭代器的类型是一个名为interatortypedef,其作用域为整个类。

vector<double>::iterator pd; //定义一个迭代器

vector<double> scores; //定义一个double类型的容器

pd = scores.begin(); //让pd指向scores的第一个元素

*pd = 22.3 //将pd指向的第一个元素的值设为22.3

++pd; //让pd指向下一个元素

为何需要迭代器:

模板使得算法独立于存储的数据类型,而迭代器是算法独立于使用的容器类型。模板还是和一个特定的数据结构(数组、链表…)关联在一起。

迭代器类型:输入迭代器、输出迭代器、正向迭代器、双向迭代器、随机访问迭代器。

输入迭代器

输入是从程序的角度来说的,即来自容器的信息被视为输入,就像来自键盘的信息对程序来说是输入一样,输入迭代器可被程序用作读取容器中的信息。只使用++来遍历容器信息。只读。

输出迭代器

将信息从程序传递给容器的迭代器叫做输出迭代器。用++来遍历容器信息。只写。

迭代器功能

输入

输出

正向

双向

随机访问

解除引用读取

解除引用写入

固定和可重复排序

++i  、 i++

--i  、 i--

i[n]

i+n

i-n

i+=n

i-=n

容器概念

容器是存储其他对象的对象。被存储的对象必须是同一种类型的,它们可以是OOP意义上的对象,也可以使内置类型值。被存储在容器中的数据为容器所有,这意味着如果容器过期了,里面的数据也会过期。(不过如果是数据是指针的话,则它指向的数据并不一定过期。)

不是任何类型的对象都能存储在容器中的,类型必须是可复制构造的和可赋值的。

序列

dequelistqueuepriority_queuestackvector都是序列,队列能够在队尾添加元素,在队首删除元素。deque表示的双端队列允许在两端添加和删除元素。

序列要求其元素按严格的线性顺序排列,不会在两次迭代之间发生变化。

表 序列的要求

表达式

返回值类型

说明

X a(n, t)

 

声明一个名为a的、由nt组成的序列

X(n, t)

 

创建一个由nt组成的匿名序列

X a(i,j)

 

声明一个名为a的序列,并将其初始化为区间[i, j)的内容

X(i, j)

 

创建一个匿名序列,并将其初始化为区间[i, j)的内容

a.insert(p, t)

迭代器

t插入p前面

a.insert(p, n, t)

void

p前面插入nt

a.insert(p, i, j)

void

p前面插入区间[i, j)的内容

a.erase(p)

迭代器

擦除删除p指向的元素

a.erase(p, q)

迭代器

删除区间[p, q]区间的元素

a.clear()

void

a清空,等价于a.clear(a.begin(), a.end())

表 序列的可选要求

表达式

返回值类型

含义

容器

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1.vector

vector是数组的一种类表示,它提供了自动内存管理功能,可以动态地改变vector对象的长度,并随着元素的添加和删除而增大和缩小,他提供了对元素的随机访问。在尾部添加和删除元素的时间是固定的,但是在头部或中间插入和删除元素的复杂度为现行时间。

vector是可翻转容器,增加了两个方法rbegin()rend(),返回的迭代器都是类级类型reverse_iterator。对这样的迭代器进行弟子增,将导致它反向遍历可反转容器。

2.deque

双端队列double-ended queue,在STL中类似于vector容器,支持随机访问,主要区别是,从deque对象的开始位置插入和删除元素的时间是固定的,不像vector中那样是线性时间。因为实现更复杂,所以它比vector实现更慢。

3.list

双向链表。除了第一个和最后一个元素外,每个元素都与前后的元素相链接,这意味着可以双向遍历链表。listvector之间关键的区别在于,list在链表中任意位置进行插入和删除的时间都是固定的。因此,vector强调的是通过随机访问进行快速访问,而list强调的是元素的快速插入和删除。

list也是可反转容器。但是list不支持数组表示法和随机访问。与矢量迭代器不同,从容器中插入和删除元素后曼联表迭代器指向的元素将不变,因为它不会移动元素的位置,知识会改变链接信息。指向某个元素的迭代器在容器插入或删除其他元素后,仍指向它原来指向的元素,但它的链接元素可能和原来不同。

 

posted @ 2014-08-27 19:13  tt_tt--->  阅读(98)  评论(0编辑  收藏  举报