面向过程的程序设计,主要是,考虑解决问题的先后顺序,措施安排等,具有典型的过程性。
面向对象的程序设计,主要是,建立在各种对象基础的软件开发,每一个具有独立特性和相应功能的个体均可以,作为一个对象加以处理。
面向对象(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类以标准形式使用new 和 delete 内存管理方式
本章总结:
介绍C++和STL模板类的基本概念,介绍类模板定义,成员模板,友元模板,函数模板,类模板的参数等内容。
模板库的历史,模板库的组件,模板库的基本结构,模板库编程概述