模板
-
use explicit class specialization:
template< > class myClass< > {}
-
模板类和函数重载的区别:
Overloading is multiple function doing similar operation Template is multiple function doing identical operations
-
如果在模板类中声明静态变量,每个实例都会有自己的静态变量
看个例子
4. 再看一个例子1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
template <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个字符串,输出是11 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include <iostream> #include <map> 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必须被定义,以保证与类相关的异常都由程序代码处理,并且不会异常终止
-
传统函数返回需要一级一级返回,但异常处理可以直接到达能够处理异常的地方
异常处理机制语法如下
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子句与抛出的异常类型匹配 程序会直接中断报错
throw后面可以跟任何表达式,整数、指针、字符常量、浮点数等,通过该操作可以创建一个异常对象并抛出
如果catch里一直找不到匹配,缺省功能是调用abort终止程序
-
异常接口声明:
void f(int x) throw (float, string *, int) { }
在函数声明中列出可能抛出的所有异常类型,如果抛出未声明的异常,可能导致程序终止、
如果不声明,函数可以抛出任何类型的异常
如果不想抛出异常,
throw()
-
异常接收:
对于基本类型的异常,使用对应类型 catch 捕获即可,但类型要严格匹配,const 修饰也要对应好,指针就是指针,string 就是 string
当异常类型是一个类对象时,不管抛出匿名对象还是局部变量,程序会生成一个匿名对象,当 catch 是普通参数时,程序会调用拷贝函数;也可以用引用和指针接收,但注意,引用和普通的形参传值不共存,否则同时捕捉,编译器不知道是哪个
文件
-
打开一个文件就是将整个文件与一个流关联;关闭文件就是取消关联
-
打开文件
1 2 3
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
打开文件并清空,之后可以进行写入 -
文件的打开方式可以组合使用