标签:include 限制 所有者 data 必须 移动构造函数 length 添加 find
构造函数 | 描述 |
---|---|
string(const char* s) |
将string对象初始化为S指向的NBTS(null-terminated-string) |
string(size_type n, char c) |
创建一个包含n个元素的string对象,其中每个元素都被初始化为字符c |
string(const string & str) |
将一个string对象初始化为string对象str (复制构造函数) |
string( ) |
创建一个默认的sting对象,长度为0 (默认构造函数) |
string(const char *s, size_ type n) |
将string对象初始化为s指向的NBTS的前n个字符,**即使超过了NBTS结尾 ** |
template\<class lter\><br>string(lter begin, Iter end) |
将string对象初始化为区间[begin, end)内的字符,其中begin和end的行为就像指针,用于指定位置 |
string(const string & str, size_type pos = 0, size_type n = npos) |
将一个sring对象初始化为对象str中从位置pos开始到结尾的字符,或从位置pos 开始的n个字符 |
string(string && str) noexcept |
这是C++11新增的,它将一个 string对象初始化为string对象str,并可能修改str (移动构造函数) |
string(initializer_list<char> il) |
这是C++11新增的,它将一个string对象初始化为初始化列表il中的字符 |
对于 C-style 字符串,有三种输入方式:
char info[100];
cin >> info; // 默认读取一个单词
cin.getline(info, 100); // 默认读取一行,并用 \0 代替 \n
cin.get(info, 100) // 读取一行,不过将 \n 留在
对于string
对象,有两种输入方法:
string stuff;
cin >> string; // 默认读取一个字符
getline(cin, stuff); // 默认读取一行,但 \n 会被抛弃
两个版本的getline()
都有一个可选参数,用来指定终止字符(默认为\n
):
cin.getline(info, 100, ‘.‘);
getline(cin, stuff, ‘.‘);
两个版本的getline()
有两个值得注意的区别:
string
版本的函数会自动调整对象大小,使之刚好能存储输入的字符串。istream
类的成员方法,而string
版本的是独立的函数。cin
是调用对象;而对于string
对象,cin
是一个函数参数**。这一点对于operator>>
同样适用。string
输入函数虽然可以自动调整string
对象的大小,但也存在一些限制:
string
对象存在最大允许长度,由string::npos
指定,通常为最大的unsigned int
值。string
的getline()
函数从输入中读取字符,并将储存到string
对象中,直到发生以下三种情况之一:
eofbit
被设置,方法fail()
和eof()
都将返回true
。string::npos
和程序可以使用的内存量之中较小的一个),将设置输入流的failbit
,方法fail()
会返回true
。string
的operator>>()
函数的行为与此类似,只是第二种情况变为不断读取直到遇到空白字符并将其留在输入流(空格、换行符、制表符等使isspace()
函数返回true
的字符)。
string
类对6个逻辑字符串都进行了重载。在比较时,将ASCII码小的字符视为小的字符。size()
和length()
都可以用来确定字符串中的字符数量。方法原型 | 描述 |
---|---|
size_type find(const basic_string &str, size_type pos = 0) const noexcept; |
从字符串的pos位置开始,查找子字符串str。如果查到,返回子字符串首次时其首字符的索引;否则,返回string::npos |
size_type find(const CharT *s, size_type pos = 0) const; |
从字符串的pos位置开始,查找子字符串s(以\n 为结尾)。如果查到,返回子字符串首次时其首字符的索引;否则,返回string::npos |
size_type find(const CharT* s, size_type pos, size_type count) const; |
从字符串的pos位置开始,查找子字符串s的前n个字符组成的子字符串。如果查到,返回子字符串首次时其首字符的索引;否则,返回string::npos |
size_type find(CharT ch, size_type pos = 0 ) const noexcept; |
从字符串的pos位置开始,查找子字符ch。如果查到,返回子字符首次时的索引;否则,返回string::npos |
注意noexcept
是在C++11之后才有的。
string
库还提供了相关的方法,它们的重载方式与find()
相同。
refind()
查找源字符串中目标字符串最后一次出现的位置。find_first_of()
查找源字符串中目标字符串中任何一个字符首次出现的位置。find_last_of()
查找源字符串中目标字符串中任何一个字符最后一次出现的位置。find_first_not_of()
查找源字符串中首次出现不属于目标字符串的任意字符的位置。find_last_not_of()
查找源字符串中最后一次出现不属于目标字符串的任意字符的位置。另外,string
对象还重载了operator=
、operator+
、operator+=
等运算符。
自动调节大小的功能:
改变字符串内容一般都会涉及到字符串长度的改变,这时不能简单地将已有的字符串加大,因为旁边的内存可能已经被占用了。因此通常的做法是为string
重新分配一块地址,并释放原来的地址。
如果一个string
对象中储存的字符串的长度会频繁地变化,会造成很多不必要的开销。这时,可以用额外的内存占用来换取这些开销的减少——使用reserve()
方法改变string
类的大小(但是不能低于默认的最小大小,也不能低于size()
或length()
)。
string str1 = "aloha0123456789"; // 5个字符
string str2 = "aloha01234567890"; // 16个字符
string str3 = "Please remember, Still water runs deep, my brother.中文"; // “中文”被视为六个字符,其实只有53个
cout << "size(): capacity()\n";
cout << str1.size() << ": " << str1.capacity() << endl;
cout << str2.size() << ": " << str2.capacity() << endl;
cout << str3.size() << ": " << str3.capacity() << endl;
str2.reserve(10);
cout << "after reserve(10):\n";
cout << str2 << ": " << str2.capacity() << endl;
str2.reserve(15);
cout << "after reserve(15):\n";
cout << str2 << ": " << str2.capacity() << endl;
str2.reserve(70);
cout << "after reserve(70):\n";
cout << str2 << ": " << str2.capacity() << endl;
size(): capacity()
15: 15
16: 16
57: 57
after reserve(10):
aloha01234567890: 16
after reserve(15):
aloha01234567890: 16
after reserve(70):
aloha01234567890: 70
在异常处理中,可能还没释放动态分配的内存程序就抛出异常。这样会造成内存泄漏。
要解决这个问题,可以使用C++中的智能指针代替普通指针。与普通指针相比,智能指针是一个类,在栈解退过程中会自动调用其构造函数,并在构造函数中释放指针所指的内存。
C++中提供了三个智能指针模板:auto_ptr
、unique_ptr
和shared_ptr
。auto_ptr
是C++98提供的解决方案,C++11中以将其摒弃(但是一般会向后兼容)。另外,还有一个特殊的智能指针weak_ptr
,需要配合shared_ptr
使用。
要使用智能指针,必须要包含头文件memory
。使用语法:
auto_ptr<Data_Type> ap(new Data_type);
unique_ptr<Data_Type> up(new Data_type);
shared_ptr<Data_Type> sp(new Data_type);
auto_ptr<string> ps1(new string("Still water runs deep."));
cout << *ps1 << endl;
auto_ptr<string> ps2 = ps1;
cout << *ps2 << endl;
为避免重复释放同一块内存,auto_ptr
采用ownership的方法(可能定义了一个标志所有者的bool
变量):当将一个auto_ptr
的值传递(赋值运算符或复制构造函数)给另一个auto_ptr
时,将转交所有权,前者将不再引用此对象。
这样虽然确实保证了对象所在内存不会被重复释放,但是可能会出于各种意外而使用原来的auto_ptr
,这显然是一个风险。
使用shared_ptr
可以避免这种风险。shared_ptr
类中有一个counter,每次调用析构函数时将counter减 1 ,并确保只有当counter为 1(初始值)时,其析构函数才会释放内存。
如果使用unique_ptr
,程序不会等到运行时才报错,在编译时编译器就会报错。这是因为unique_ptr
禁止使用一个可能会长期存在的左值进行初始化。但是神奇的是,unique_ptr
允许使用一个临时的右值进行初始化,并且能正确地运行(unique_ptr
使用了移动构造函数和右值引用):
auto_ptr<string> ps1(new string("Still water runs deep."));
unique_ptr<string> ps2;
ps2 = ps1; // error
unique_ptr<string> ps3;
ps3 = unique_ptr<string>(new string("aloha!"));
另外,如果要使用new[]
,就一定要使用unique_ptr
,因为只有uinque_ptr
有使用new[]
和delete[]
的版本。使用示例:
unique_ptr<string[]> pad(new string[5]);
在头文件vector
中定义了vector
类。可以像使用数组一样使用vector
(虽然vector
的用法要更多)。
要创建vector
,可以使用通常的<type>语法来指定要存储的数据的类型,并通过构造函数指定数据的数量。
#include <vector>
// ...
vector<int> arri(5);
因此可以用索引语法访问vector
对象中的数据。
可对vector
进行的操作:
size()
:返回容器中的元素个数。swap()
:交换两个容器的内容。begin()
:返回指向容器中的一个元素的迭代器。end()
:返回指向一个超出容器尾的迭代器。vector
及其他部分容器具有的方法:
push_back()
:在容器结尾添加元素。erase()
:删除指定“[)”区间的元素。insert()
:在指定位置前插入一组数据。第一个参数为迭代器,指定插入位置。插入的数据可以用两个迭代器确定,也可以使用新增的初始化列表语法。STL通过为每种容器都定义一个迭代器,给所有的容器都提供了统一的接口。
可以像下面这样使用迭代器(其实STL为下面的操作提供了更简便的方法):
vector<int> nums(5);
nums = {1, 2, 3, 4, 5};
vector<int>::iterator pd = nums.begin();
for(pd; pd != nums.end(); ++pd)
cout << *pd << ‘\t‘;
foreach()
,前两个迭代器参数指定要进行操作的区间,第三个函数指针参数指定要进行的操作。
vector<Review>::iterator pr;
for (pr = books.begin(); pr != books.end(); pr++)
ShowReview(*pr);
// 等价于以下代码
for_each(books.begin(), books.end(), ShowReview);
Random_shuffle()
,接受两个指定区间的迭代器参数,并随机排列该区间中的元素。这个函数要求容器支持随机访问。
sort()
:该函数也要求容器支持随机访问。该函数有两个版本:
接受两个指定区间的迭代器,使用定义在容器内的<
运算符对容器内的元素进行排序。
接受两个指定区间的迭代器,并接受一个指定操作的函数指针。
bool WorseThan(const Review & r1, const Review & r2)
{
if(r1.title < r2.title)
return true;
else if(r1.title == r2.title && r1.rating < r2.rating)
return true;
else
return false;
}
sort(books.begin(), books.end(), WorseThan);
标签:include 限制 所有者 data 必须 移动构造函数 length 添加 find
原文地址:https://www.cnblogs.com/alohana/p/12571711.html