Skip to content

模板

  1. use explicit class specialization:

    template< > class myClass< > {}

  2. 模板类和函数重载的区别:

    Overloading is multiple function doing similar operation Template is multiple function doing identical operations

  3. 如果在模板类中声明静态变量,每个实例都会有自己的静态变量

    看个例子

     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
    
    4. 再看一个例子

     1
     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;
    }
    
    如果输入10个字符串,输出是1

    因为map中的键类型是char*,由于str是一个字符数组,每次输入新的字符串时,str的内容被覆盖,但是str的地址保持不变,因此map实际上一直在使用同一个键,并不断更新与该键关联的值,无论输入多少个不同的字符串,map中只会有一个元素,最终输出的m.size()是1,而不是输入的字符串数量

  4. vector<int> v = 1是不合法的,没有接受单个整数作为参数的构造函数

    vector<int> v = (10, 1)和上面一样

  5. 迭代器的分类:输入迭代器,前向迭代器,双向迭代器

  6. string s;实际上初始化了一个空字符串,不能用下标操作符去修改里面的字符

  7. getline(cin, s),读取直到遇到下一个换行符 cin >> n,如果用户输入一个字符并按下回车,回车符仍然留在输入流中,如果此时执行getline(cin, s),读到换行符,直接停止读取,返回一个空字符串

  8. get()getline()的区别:

    前者不消耗换行符,如果连续使用,下一个get()会立即遇到上一个留下的换行符并停止读取

    后者消耗换行符,如果连续调用,每次调用都会从下一行开始读取

异常处理

  1. 异常是程序运行期间抛出的问题,处理异常可以避免程序不正常终止

  2. 如果在目标位置没有找到要打开的文件,将会产生异常

  3. 如果要捕捉异常,需要创建一个对象

    多个捕获块可以合并成一个

    e.g.:

    • IOExceptions处理I/O异常

    • ClassNotFoundException处理未定义类异常

    • UnsupportedEncodingException处理不支持的字符编码异常

  4. 如果一个捕获块接受不止1个异常,那么catch的参数是final(什么意思?)

  5. 如果类产生多个异常,他们的catch block必须被定义,以保证与类相关的异常都由程序代码处理,并且不会异常终止

  6. 传统函数返回需要一级一级返回,但异常处理可以直接到达能够处理异常的地方

    异常处理机制语法如下

     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终止程序

  7. 异常接口声明:void f(int x) throw (float, string *, int) { }

    在函数声明中列出可能抛出的所有异常类型,如果抛出未声明的异常,可能导致程序终止、

    如果不声明,函数可以抛出任何类型的异常

    如果不想抛出异常,throw()

  8. 异常接收:

    对于基本类型的异常,使用对应类型 catch 捕获即可,但类型要严格匹配,const 修饰也要对应好,指针就是指针,string 就是 string

    当异常类型是一个类对象时,不管抛出匿名对象还是局部变量,程序会生成一个匿名对象,当 catch 是普通参数时,程序会调用拷贝函数;也可以用引用和指针接收,但注意,引用和普通的形参传值不共存,否则同时捕捉,编译器不知道是哪个

文件

  1. 打开一个文件就是将整个文件与一个流关联;关闭文件就是取消关联

  2. 打开文件

    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)
    
  3. 打开文件的目的是使文件对象与磁盘文件建立联系,但文件读写过程中程序不会直接和磁盘文件进行数据交换

    关闭文件的目的包括将输出的数据写入硬盘文件、释放内存中的文件对象等

  4. ios 是基础类,istream、ostream 是 ios 的直接派生类

    iostream 是 istream 和 ostream 的多重继承来的类,不是直接从 ios 继承的

    strstreambase 不是 ios 的直接派生类,它处理基于字符串的流

  5. 对磁盘文件进行操作时,以 ios::out 模式打开的文件,可实现创建一个可以写入的、新的空文件;如果文件已经存在,则删除以前的内容再写入新数据

    ifstream 类对象默认打开方式 ios::in,ostream 类对象默认打开方式 ios::out

    ios::app 追加模式,用于输出操作,确保写入的数据总是追加到文件末尾

    ios::trunc 打开文件并清空,之后可以进行写入

  6. 文件的打开方式可以组合使用