【String类和标准模板库】

1.string类

2.智能指针模板类

3.标准模板库

4.泛型编程

5.函数对象

6.算法

7.其他库


1.string类

string类是由头文件string支持的,要使用类,关键要知道它的公有接口。

1.1构造字符串

#include<iostream>
#include<string>

using std::string;
using std::cout;
using std::endl;
int main()
{
	string one("Lottery Winner!");
	string two(20, '-');
	string three(one);
	string four;
	const char* s = "All's well that ends well";
	char sc[] = "All's well that ends well";
	string five(s, 20);
	string six(sc + 5, sc + 10);
	string six_2(&five[5], &five[10]);
	string seven = { 'L','O','P','T' };
	cout << one << endl << two << endl
		<< three << endl << four << endl << five << endl
		<< six << endl << six_2 << endl << seven << endl;
	one[0] = 'P';
	three = one + two;
	cout << one << endl << three << endl;
	return 0;
}

 注:数组名相当于指针,所以:

string six(sc + 5, sc + 10);

而对象名不是指针,所以要下标索引加取地址符号:

	string six_2(&five[5], &five[10]);

移动构造函数再第18章讲解,最后一个构造函数使得能够将列表初始化方法用于string类,本章后边更深刻讨论initializer_list。 

1.2string类输入

1.2.1C风格

3种输入方式:

char info[100];
	cin >> info;
	cin.getline(info, 100);
	cin.get(info, 100);

1.2.2string对象

2种方式:

string lname;
	cin >> lname;
	getline(cin, lname);

string具有自动调整大小的功能,不需要指定长度,并且string类,所以cin作为参数。

string函数停止读入条件:

1.到达string对象最大允许长度:(string::npos或可供分配的内存字节数中较小的一个) 

2.到达文件末尾

3.遇到分界字符(默认为\n)

对于>>输入字符,程序在读到空白字符(空格 换行 制表)就会停止。

#include<iostream>
#include<string>
#include<fstream>
#include<cstdlib>
using namespace std;
int main()
{
	ifstream fin;
	fin.open("C:\\Users\\HXY\\Desktop\\abc.txt");
	string item;
	int count = 0;
	getline(fin, item, ':');
	while (fin)
	{
		++count;
		cout << count << ":" << item << endl;
		getline(fin, item, ':');
	}
	cout << "Done!";
	fin.close();
	return 0;
}

当指定了分界字符后,换行符就成了普通字符。

第4行第一个是换行符。

1.3使用字符串

1.字符串可以用6个关系运算符直接比较;

2.类方法 size()和length()返回字符串长度;

3. = += 赋值和附加字符串;

4.查找方法:

现在不返回std::npos,而是返回-1.(2022年)

 rfind()方法和find()类似只不过查找最后一次出现的位置;
find_first_of()查找参数中任何一个字符第一次出现的位置;
find_last_of()查找参数中任何一个字符最后一次出现的位置;
find_first_not_of()查找不在参数中的任何一个字符第一次出现的位置;
find_last_not_of()查找不在参数中的任何一个字符最后一次出现的位置;

#include<iostream>
#include<string>
using namespace std;
int main()
{
	string s1("hark");
	string s2("cobra");
	string s3 = "shark";
	int i = s3.find(s1, 0);
	int j = s2.find('b', 0);
	int j2 = s2.find('j', 0);
	int k = s3.find_first_of(s2);
	cout << i << endl
		<< j << endl
		<< j2 << endl
		<< k << endl;
	return 0;
}

1.4string其他功能

方法capacity()返回当前分配给字符串的内存块大小,reserve()请求内存块的最小长度。

#include<iostream>
#include<string>
using namespace std;
int main()
{
	string s1("hark");
	string s2("cobra");
	string s3 = "shark";
	cout << "size:\n";
	cout << s1.size() << endl << s2.size() << endl << s3.size() << endl;
	cout << "capacity:\n";
	cout << s1.capacity() << endl << s2.capacity() << endl << s2.capacity() << endl;
	s2.reserve(70);
	cout << s2.capacity();

	return 0;
}

c_str()方法返回一个指向C风格字符串的指针,内容与对象相同。

1.5字符串种类

模板basic_string有4个具体化,除了使用char类型,还可以使用wchar_t,char16_t,char32_t.

2.智能指针模板类

2.1智能指针的引入

智能指针是行为类似于指针,但是是一个类对象,可用于帮助管理动态内存分配的智能指针模板。

智能指针模板的存在是为了在存在动态分配函数终止(正常或异常),使得动态分配的内存清除掉,需要一个析构函数,所以智能指针就出现了。

2.2使用智能指针

以下三个智能指针模板(auto_ptr、unique_prt、shared_ptr)位于名称空间std中,定义在头文件memory中,使用通常的模板语法来实例化所需类型的指针,我们便不需要记住稍后释放这些内存。

auto_ptr<double> pd(new double);//使用指向double的内存地址来初始化智能指针对象
auto_ptr<string> ps(new string);
#include<iostream>
#include<memory>
#include<string>
using namespace std;
class report
{
private:
	string str;
public:
	report(const string s) :str(s) { cout << "Object created.\n"; };
	~report(){ cout << "Object deleted.\n"; }
	void comment() { cout << str; }

};
int main()
{
	{
		auto_ptr<report> p1(new report("using auto_ptr"));
		p1->comment();
	}//离开代码块,指针将过期
	
	{
		unique_ptr<report> p2(new report("using unique_ptr"));
		p2->comment();
	}
	
	{
		shared_ptr<report> p3(new report("using shared_ptr"));
		p3->comment();
	}
	
	return 0;
}

 智能指针很多地方都类似于常规指针,解引用、->访问结构成员,赋值给相同类型的常规指针(显式类型转换),赋值给同类型的智能指针。无论如何,都不能将智能指针用于非动态存储的对象或变量。

显式类型转换:

shared_ptr<double> p1;
	double* p2 = new double;
	p1 = p2;   不允许
	p1 = shared_ptr<double>(p2);  这才正确
	shared_ptr<double> pshared = p2;  不允许
	shared_ptr<double> pshared(p2);  这才正确(复制构造函数)
	return 0;

2.3有关智能指针的注意事项

智能指针在复制的时候,如果执行浅复制,则会导致内存释放两次,严重错误。

shared_ptr创建智能更高的指针,跟踪引用特定对象的智能指针数,仅当最后一个指针过期时,才会调用析构函数;

auto_ptr 和 unique_ptr会建立所有权概念,对于特定的对象,只能有一个指针指向它,如果进行赋值操作,则所有权会转移,auto_ptr被转移的所有权的指针指向空指针,不安全;而unique_ptr不允许赋值操作,除非存在一个临时对象,临时对象的所有权转让给新对象,老对象被销毁,这时赋值是可以用的。

unique_ptr可用于数组变体。new  delete、new[]   delete[]要配合使用,unique_ptr可以满足这种情况。

2.4选择智能指针

如果程序要使用多个指向同一个对象的指针,用shared_ptr;否则用unique_ptr(auto_ptr被C++11抛弃)。

3.标准模板库(STL)

STL提供了一组表示容器(存储同类型若干值)、迭代器(遍历容器的广义指针)、函数对象(类似于函数的对象)和算法(完成特定任务)的模板。STL不是面对对象的编程,而是泛型编程。

3.1模板类vector

vector在头文件vector中定义里模板,存储了一组可以随机访问的值,使用索引来直接访问元素。要创建vector模板对象,通常<type>指出要使用的类型,可以使用动态内存分配,可以使用变量来指出需要多少矢量。

	vector<double> p1(5);
	int n;
	cin >> n;
	vector<string> p2(n);

默认使用new和delete来动态分配内存,可以选择分配器(STL模板容器接受可选的模板参数)。

#include<iostream>
#include<vector>
#include<string>
using namespace std;

int main()
{
	vector<int> ratings(5);
	vector<string> titles(5);
	for (int i = 0; i < 5; i++)
	{
		cout << "Enter title #" << i + 1 << ":";
		getline(cin, titles[i]);
		cout << "Enter your ratings:";
		cin >> ratings[i];
		cin.get();
	}
	for (int i = 0; i < 5; i++)
	{
		cout << titles[i] << endl;
		cout << "Ratings:" << ratings[i] << endl;
	}
}

3.2可对矢量执行的操作

所有的STL容器都提供了一些基本的方法:

size()——返回容器元素数目

swap()——交换两个容器的内容 

begin()——返回一个指向容器中第一个元素的迭代器

end()——返回一个表示超过容器尾的迭代器

迭代器:广义指针,可以对其使用解引用和递增,迭代器的存在让STL存在能够为各种不同的容器类提供统一的接口。每个容器都定义了一个合适的迭代器,该迭代器的类型是一个名为iterator的typedef,作用域为整个类。

vector<int>::iterator pd;
	pd = ratings.begin();
	pd[2] = 23;
	pd++;

auto存在让一切变得简单
	auto p = ratings.begin();

所有容器都有上述方法,vector包含一些只有某些STL容器才有的方法。

push.back()将元素添加到矢量的末尾,在编写或运行程序时,无需了解元素数目。

erase()删除矢量中给定区间的元素,接受两个迭代器参数。

insert()在矢量中插入元素;,接受三个迭代器参数,第一个为插入的位置。

#include<iostream>
#include<vector>
#include<string>
using namespace std;
struct Review
{
	string title;
	int rating;
};
bool FillReview(Review& rr);
void ShowReview(const Review& rr);
int main()
{
	vector<Review> books;
	Review temp;
	while (FillReview(temp))
	{
		books.push_back(temp);       //添加元素
	}
	int num = books.size(); //返回长度

	auto  pd = books.begin();   //指针
	f
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值