《C++STL标准程序库开发指南》第一章,类模板简介

面向过程的程序设计,主要是,考虑解决问题的先后顺序,措施安排等,具有典型的过程性。
面向对象的程序设计,主要是,建立在各种对象基础的软件开发,每一个具有独立特性和相应功能的个体均可以,作为一个对象加以处理。
面向对象(Object Oriented,OO)
文件

头文件<fstream>
ifstream 和 wifstream   用来读取文件
ofstream 和 wofstream	用来将数据写入文件
fstream 和 wfstream		用于读/写文件,wfstream是字读取操作
filebuf 和 wfilebuf  	用来进行实际的字符读写,
ios_base::in			//打开文件,用于读取
ios_base::out			//打开文件,用于改写或者写入
ios_base::ate			//打开文件,用于将文件指针移到文件末尾
ios_base::app			//打开文件,写入时始终添加入尾端
ios_base::trunc			//打开文件,将先前的内容移除
ios_base::binary		//以二进制形式打开文件

文件流状态检查:fail() is_open() eof()

使用临时文件,cstdio库中,char* tmpnam(char* pszname)创建一个临时文件名

#include<iostream>
#include<cstdio>
//TMP_MAX,L_tmpnam变量的值是随机的
void main()
{
	using namespace std;
	cout<<"This system can generate up tp"<<TMP_MAX<<"temporary name of up to"<<L_tmpnam<<" characters.\n";
	char pazName[L_tmpnam] = {'\0'};
	cout<<"Here are ten name: \n";
	for(int i =0;i<10;i++)
	{
		tmpnam(pazName);
		cout<<pszName<<endl;
	}
	return;
} 

一般情况,当程序处理异常时一般调用terminate()函数
当在程序中调用其他命令,或者可执行文件时,可选用system()函数

异常处理(C++异常处理代码是 catch子句)

异常已经发生,当异常被try中的语句抛出时,系统通过查看try块后的catch子句列表,来查找能够处理该异常的catch子句。

C++ STL 定义了标准库异常库 exception,头文件<exception>中,但是异常类exception不能捕捉所有的异常

STL的背后蕴藏着泛型化程序设计(GP)的思想,泛型化,是英语翻译来的,本书作者认为,称"普通"更恰当。

template<class Type>
list stack map等
《STL源码剖析》下一本书

#include<iostream>
using namespace std;
template<class T>
class B
{
public:
	static int count;
	static long size;
public:
	static long GetSize()
	{
		return size;
	}
	static int GetCount()
	{
		return count;
	}
};
template<class T> int B<T>::count =0;
template<class T> long B<T>::size =2;
void main()
{
	int cnt;
	long nsize;
	B<int> my;
	my.count =2;
	my.size = 3;
	cnt = my.GetCount();
	nszie = my.GetSize();
	cout<<cnt<<"  ,"<<nsize<<endl;
}

成员模板(模板可以做结构,类或者模板类的成员),在完全实现STL设计中,必须使用这项特性。

template<class T>
class S
{
public:
	template<class T2> int compare(const T2&);
	.......
};
template<class T>
template<class T2>int S<T>::compare(const T2& s)
{
	.......
}
template <typename T>class B
{
public:
	template <typename V> class H
	{
	public:
		V m;
		.....
	}
	....
}
*成员模板不能为虚(virtue)
*成员函数模板不能重载基类的虚函数
*局部类,不能拥有成员模板
*析构器不能是模板类型

友元模板(友元机制允许一个类对其非公有制成员的访问权,授予给制定的函数或者

class Screen{
	friend class Windows;
	.......
}

类模板中,友元定义主要分为以下3种:
1 非模板函数,类作为实例类的友元
2 模板函数,模板类作为同类型实例类的友元
3 模板函数,类作为不同类型实例类的友元

1 非模板函数,类作为实例类的友元
class A
{
	void AF();
};
template <class Type>
class Queue
{
	friend class B; //类B不需要事先声明
	friend void A();//函数A()
	friend void A::AF(); //类A必须事先声明
}

2 模板函数,模板类作为同类型实例类的友元
template <class Type> class A{...};
template <class Type> void D(){B <Type>};
template <class Type> class C{void Cf();...};

template <class Type> class B
{
	friend class A<Type>;		//模板A需要先定义或声明
	friend void D(B <Type>);	//模板函数A()需要先定义或声明
	friend void C<type>::Cf();	//模板类C必须先定义
};

3 模板函数,类作为不同类型实例类的友元
template<class T>
class B
{
	friend <class Type> friend class A;
	template <class Type> friend void D(B <Type>);
	template <class Type> friend void C::Cf();
}

函数模板(可以定义参数化的非成员函数,使程序员能够用不同类型的参数调用相同的函数,由编译器决定使用哪种类型,从模板函数中生成相应的代码)

template<typename T>
void print(const T& var)
{
	cout<<var<<endl;
}

#include<iostream>
#include<string>
#include<sstream>
template <typename T>
T fromString(const std::string& s)
{
	std::istringstream is(s);
	T t;
	is >> t;
	return t;
}
template <typename T>
std::string toString(const T& t)
{
	std::ostringstream s;
	s<<t;
	return s.str();
}

类模板的参数(模板的参数,可以是类型参数,也可以是常规类型参数,并且一个模板可以有多个参数)

template <class T1,class T2,class T3> class classname;
template <typename T1,typename T2,typename T3> class classname;

关键字typename的使用,主要解决,由类模板机制,带来的语义歧义,使模板声明更加直观。
类模板及其成员函数,使用typename关键字,限定所有对参数化类型中定义类型的引用。编译器看到typename关键字,就知道其后紧跟的是,数据类型,在分析代码时,假定类型的名字,通过实例来填充。标准C++要求,如果类型在模板化的类中定义,在模板中引用该类型时,都要使用typename限定符。

template <class T>
class Y
{
	typedef typename T::A TA;
	TA* abc;
	.....
}

#include<iostream>
template <class T>
class Table
{
	typename T::iter t; //typename说明,T代表类型
public:
	explicit Table(const typename T::iter& ti):t(ti){}
	void show()
	{
		typename T::iter* y;
		y = &t;
		std::cout<<(*y)->p<<std::endl;
	}
};
class card
{
public:
	typedef card* iter; //***********************
	int p;
	card(int pos):p(pos){}
};
void main()
{
	card pc(3);
	Table<card>S_Table(&pc);
	S_Table.show();
	return;
}
输出:3

关键字typename和关键字class

模板库简介(广义上3类:algorithm,container,iterator)
STL 13个头文件:

<algorithm>
<deque>
<functional>
<iterator>
<vector>
<list>
<map>
<memory>
<numeric>
<queue>
<set>
<stack>
<utility>

在这里插入图片描述
容器

STL常见类型:
向量类,链表类,双向队列类, 集合类,图类,等
vector<int> l;
for(int i=0;i<100;i++)
	l.push_back(i);
map容器,进行二维元素的管理
map<string,string,less<string>> cap;//按从小到大排序
cap["Ark"] = "Little Rock";
cap["New"] = "Albany";
map类似二维数组,但是比二维数组灵活很多。

STL中提供的容器

vector<T> 一种向量
list<T> 一个双向链表容器
queue<T> 一种队列容器
stack<T> 一个栈容器
deque<T> 双端队列容器
priority_queue<T> 一种按值排序的队列容器
set<T> 一种集合容器
multiset<T> 一种允许重复元素的集合容器
map<key,val> 一种关联数组容器
multimap<key,val> 一种允许出现重复key值的关联数组容器

容器分为两大类:序列式容器,关联式容器。

序列式容器:vector list deque 
关联式容器: set map multiset multimap

算法
常见的部分算法如下:

for_each()
find()
find_if()
count()
count_if()
replace()
replace_if()
copy()
unique_copy()
sort()
equal_range()
merge()

迭代器

迭代器,为访问容器提供通用的方法,类似C++指针
	   当参数化类型是C++内部类型时,即C++指针
常见的迭代器类别:
		输入,输出,前向,双向,随机访问
迭代器,使算法和容器分离开,成为可能,算法是模板,其类型为迭代器,不会局限于单一容器。

仿函数

STL还有两个最重要的内容:仿函数 和 内存配置器。
STL包含大量仿函数,仿函数,可以理解为函数的一般形式。仿函数有几种不同的约束,对编程来讲,仿函数十分重要。
推导历史
在标准C++规范中,函数调用一般使用指针,当调用函数时,只需要告诉函数的地址即可
static int cmp(int *i,int*j){return (*i-*j);}
当需要调用,上述函数时,只需要提供函数的地址即可
qsort(a,10,sizeof(int),cmp);
此方法,最大缺点,效率低。为了提高效率,STL定义仿函数概念,
定义一个仿函数,其特征就是使用,operator 来定义
struct three_mul
{
	bool operator(int& v)
	{
		return (v%3 ==0)
	}
}
上面定义了一个仿函数,通过运算符定义能显著提高效率???????能看出啥???
for_each(myvector.begin(),myvector.end(),three_mul);

内存配置器
STL包括底层的内存分配和释放。Allocators非常少见

常见配置器:istream_iterator,提供了函数copy的接口
Adapter 对于STL技术非常重要。STL提供3种容器配接器
stack<Container>
queue<Container>
and deque<Container>
STL主要有 迭代器,算法,容器,仿函数,内存配置器,配接器:6部分组成。
容器,是同质的,即存储的值类型相同
算法,是完成特定任务的处方,
迭代器,能够用来遍历容器的对象,与能够遍历数组的指针类似,是广义指针
仿函数,是类似,函数的对象,可以是类对象,或者,函数指针
allocator类以标准形式使用newdelete 内存管理方式

本章总结:

介绍C++和STL模板类的基本概念,介绍类模板定义,成员模板,友元模板,函数模板,类模板的参数等内容。
模板库的历史,模板库的组件,模板库的基本结构,模板库编程概述
发布了30 篇原创文章 · 获赞 5 · 访问量 2220

猜你喜欢

转载自blog.csdn.net/weixin_44408476/article/details/104872948