string类
c++提供的处理字符串的类,要了解其类中的成员函数。
string类中有七个构造函数,c++11又新增了两个构造函数:
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string one("Lottery winner");
cout << one << endl;
string two(20, '$');
cout << two << endl;
string three(one);
cout << three << endl;
one += " Oops";
cout << one << endl;
two = "Sorry, That was ";
three[0] = 'P';
string four;
four = two + three;
cout << four << endl;
char alls[] = "All's well that ends well";
string five(alls, 20);
cout << five << endl;
string six(alls+6, alls+10);
cout << six << ", ";
string seven(&five[6], &five[10]);
cout << seven << "..." << endl;
string eight(four, 7, 16);
cout << eight << endl;
return 0;
}
string类中的函数有很多,不作详细总结了,需要的时候再看吧。
分配一个比实际字符串大的内存块,为字符串提供了增大空间,如果不断扩大,超过了内存块,程序将分配一个大小为原来两倍的新内存块。:
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string empty;
string small = "bit";
string larger = "Elephants are a girl's best friend";
cout << "Sizes:" << endl;
cout << "\t empty: " << empty.size() << endl;
cout << "\t small: " << small.size() << endl;
cout << "\t larger: " << larger.size() << endl;
cout << "Capacities:"<< endl;
cout << "\t empty: " << empty.capacity() << endl;
cout << "\t small: " << small.capacity() << endl;
cout << "\t larger: " << larger.capacity() << endl;
empty.reserve(50);
cout << "Capacity after empty.reserve(50): " << empty.capacity() << endl;
return 0;
}
智能指针模板类
智能指针是行为类似于指针的类对象,在以往的指针中,最后需要delete,但如果不收回,会导致内存泄漏,如果将指针作为一种类对象,其delete在类的析构函数中,会自动调用,也就会自动delete,这会方便很多。
目前有三种智能指针模板:auto_ptr,unique_ptr,shared_ptr,可以将new获得的地址传递赋给这种对象:
auto_ptr<double> pd(new double);
auto_ptr<string> ps(new string);
new double是new返回的指针,指向新分配的内存块,它是构造函数的参数。
有关注意事项:
auto_ptr<string> ps(new string("hello world!"));
auto_ptr<string> pt;
pt = ps;
上述代码,两个指针指向同一个string对象,调用两次析构函数,也就delete两次,显然是错误的。解决方法:
- 定义赋值运算符,使之执行深复制
- 建立所有权概念,即一个对象,只能有一个智能指针可拥有它,赋值会转让所有权,即auto_ptr,unique_ptr的策略
- 创建智能更高的指针,跟踪引用特定对象的智能指针数,称为引用计数,赋值时,计数加一,指针过期,计数减一,最后一个指针过期,再调用delete。
所以将上述代码改为shared_ptr即可。
而unique_ptr优于auto_ptr,因为auto_ptr会造成一个智能指针不再指向有效数据,所以unique更安全。
标准模板库
STL提供了一组表示容器,迭代器,函数对象和算法的模板
之前的vector就是一个容器类,可以当作数组使用,里面也有很多成员函数下面介绍一些:
迭代器:指针广义化,为各种不同的容器类提供统一的接口
vector<double> :: iterator pr; //迭代器pr,就像一个指针一样使用
struct Review
{
string title;
int rating;
};
vector<Review> books; //定义一个对象
Review temp;
while(FillReview(temp))
books.push_back(temp); //将普通的Review结构体加入到前面定义的对象中,添加数据。
int num = books.size(); //对象现有数据个数
if(num > 0)
{
cout << "You entered the following: " << endl;
for(int i = 0; i < num; i++)
ShowReview(books[i]);
cout << "Reprising: " << endl;
vector<Review> :: iterator pr;
for(pr = books.begin(); pr != books.end(); pr++)
ShowReview(*pr);
vector<Review> oldlist(books); //定义一个新的对象,将已有的对象数据拷贝给新对象
if(num > 3)
{
books.erase(books.begin() + 1, books.begin() + 3); //容器的第一个数据
cout << "After erasing: " << endl;
for(pr = books.begin(); pr != books.end(); pr++) //容器的最后一个数据
ShowReview(*pr);
books.insert(books.begin(), oldlist.begin()+1, oldlist.begin()+2);//insert表示给容易插入数据,第一个参数是插入的位置,后两个是插入的数据
cout << "After inserting: " << endl;
for(pr = books.begin(); pr != books.end(); pr++)
ShowReview(*pr);
}
books.swap(oldlist); //排序
cout << "After swaping: " << endl;
for(pr = books.begin(); pr != books.end(); pr++)
ShowReview(*pr);
上面是最基本的操作,还有很多STL函数,介绍三个具有代表性的:
vector<Review> :: iterator pr;
for(pr = books.begin(); pr != books.end(); pr++)
ShowReview(*pr);
//上述代码替换为
for_each(books.begin(),books.end(),ShowReview);
接受三个参数,前两个是定义容器中区间的迭代器,最后一个是指向函数的指针(函数对象),**for_each()**函数会对容器相应区间内各个元素执行传入的函数对象操作。因此可以,代替for循环,这样可以避免显式使用迭代器变量。
Random_shuffle() 函数接受两个指定区间的迭代器参数,并随机排列区间中的元素
sort():接受两个定义区间的去迭代器参数,使用为存储再容器中的类型元素定义的<运算符,对区间元素进行操作,也就是升序。也可以自己重载<运算符,达到自己想要的排序方法。
基于范围的for循环是为用于STL设计的:
double prices[5] = {1.1, 2.3, 6.1, 12.6, 5.6};
for(double x : prices)
cout<<x<<std::endl;
这种for循环中,括号内的代码声明一个类型与容器存储的内容相同的变量,然后指出了容器的名称,接下来,循环第使用指定的变量依次访问容器中的每个元素.