Oop_pta_6
模板
- use explicit class specialization:
template< > class myClass< > {}
- 模板类和函数重载的区别:
Overloading is multiple function doing similar operation
Template is multiple function doing identical operations - 如果在模板类中声明静态变量,每个实例都会有自己的静态变量
看个例子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19template <typename T>
void test(const T &x)
{
static int count = 0;
cout << "x = " << x << " count = " << count << endl;
++count;
return;
}
int main()
{
test<float>(2.0);
test<int>(3);
test<int>(3);
test<double>(2.2);
}
//x = 2 count = 0
//x = 3 count = 0
//x = 3 count = 1
//x = 2.2 count = 0 - 再看一个例子如果输入10个字符串,输出是1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using namespace std;
std::map<char *, int> m;
const int MAX_SIZE = 100;
int main()
{
char str[MAX_SIZE];
for (int i = 0; i < 10; i++)
{
std::cin >> str;
m[str] = i;
}
std::cout << m.size() << std::endl;
}
因为map中的键类型是char*,由于str是一个字符数组,每次输入新的字符串时,str的内容被覆盖,但是str的地址保持不变,因此map实际上一直在使用同一个键,并不断更新与该键关联的值,无论输入多少个不同的字符串,map中只会有一个元素,最终输出的m.size()是1,而不是输入的字符串数量 vector<int> v = 1
是不合法的,没有接受单个整数作为参数的构造函数vector<int> v = (10, 1)
和上面一样- 迭代器的分类:输入迭代器,前向迭代器,双向迭代器
string s;
实际上初始化了一个空字符串,不能用下标操作符去修改里面的字符getline(cin, s)
,读取直到遇到下一个换行符cin >> n
,如果用户输入一个字符并按下回车,回车符仍然留在输入流中,如果此时执行getline(cin, s)
,读到换行符,直接停止读取,返回一个空字符串get()
和getline()
的区别:
前者不消耗换行符,如果连续使用,下一个get()会立即遇到上一个留下的换行符并停止读取
后者消耗换行符,如果连续调用,每次调用都会从下一行开始读取
异常处理
- 异常是程序运行期间抛出的问题,处理异常可以避免程序不正常终止
- 如果在目标位置没有找到要打开的文件,将会产生异常
- 如果要捕捉异常,需要创建一个对象
多个捕获块可以合并成一个
e.g.: IOExceptions处理I/O异常
ClassNotFoundException处理未定义类异常
UnsupportedEncodingException处理不支持的字符编码异常 - 如果一个捕获块接受不止1个异常,那么catch的参数是final(什么意思?)
- 如果类产生多个异常,他们的catch block必须被定义,以保证与类相关的异常都由程序代码处理,并且不会异常终止
- 传统函数返回需要一级一级返回,但异常处理可以直接到达能够处理异常的地方
异常处理机制语法如下throw后面可以跟任何表达式,整数、指针、字符常量、浮点数等,通过该操作可以创建一个异常对象并抛出1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//异常发生第一现场,抛出异常
void function( ){
//... ...
throw /*表达式*/;
//... ...
}
//在需要关注异常的地方,捕捉异常
try{
//程序
function(); //把function至于try中
//程序
}catch(/*异常类型声明*/){ //比如只写一个int
//... 异常处理代码 ...
}catch(/*异常类型 形参*/){ //形参将会取得抛出的值
//... 异常处理代码 ...
}catch(...){ //抛出的其它异常类型,可以接收任意类型
//
}//如果没有catch(...) 并且没有catch子句与抛出的异常类型匹配 程序会直接中断报错
如果catch里一直找不到匹配,缺省功能是调用abort终止程序 - 异常接口声明:
void f(int x) throw (float, string *, int) { }
在函数声明中列出可能抛出的所有异常类型,如果抛出未声明的异常,可能导致程序终止
如果不声明,函数可以抛出任何类型的异常
如果不想抛出异常,throw()
- 异常接收:
对于基本类型的异常,使用对应类型catch捕获即可,但类型要严格匹配,const修饰也要对应好,指针就是指针,string就是string
当异常类型是一个类对象时,不管抛出匿名对象还是局部变量,程序会生成一个匿名对象,当catch是普通参数时,程序会调用拷贝函数;也可以用引用和指针接收,但注意,引用和普通的形参传值不共存,否则同时捕捉,编译器不知道是哪个
文件
- 打开一个文件就是将整个文件与一个流关联;关闭文件就是取消关联
- 打开文件
ofstream ofile; ofile.open("D:\a.txt", ios::binary)
fstream iofile; iofile.open("a.txt", ios::ate)
ifstream ifile("D:\a.txt", ios::binary)
- 打开文件的目的是使文件对象与磁盘文件建立联系,但文件读写过程中程序不会直接和磁盘文件进行数据交换
关闭文件的目的包括将输出的数据写入硬盘文件、释放内存中的文件对象等 - ios是基础类,istream、ostream是ios的直接派生类
iostream是istream和ostream的多重继承来的类,不是直接从ios继承的
strstreambase不是ios的直接派生类,它处理基于字符串的流 - 对磁盘文件进行操作时,以
ios::out
模式打开的文件,可实现创建一个可以写入的、新的空文件;如果文件已经存在,则删除以前的内容再写入新数据
ifstream类对象默认打开方式ios::in
,ostream类对象默认打开方式ios::out
ios::app
追加模式,用于输出操作,确保写入的数据总是追加到文件末尾ios::trunc
打开文件并清空,之后可以进行写入 - 文件的打开方式可以组合使用
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 slx's NOTEBOOK!