• 面向对象程序设计-C++ Stream & Template & Exception【第十五次上课笔记】


    这是本门《面向对象程序设计》课最后一次上课,刚好上完了这本《Thinking in C++》 :)

    这节课首先讲了流 Stream 的概念

    平时我们主要用的是(1)在屏幕上输入输出的 cin cout 流

             (2)在文件中输入输出的 ifstream ofstream 流

             (3)在字符串中输入输出的 istringstream ostringstream istrstream ostrstream 流

    具体实例可以看以下代码:

    /*************************************************************************
        > File Name: Code09.cpp
        > Author: Jeremy Wu
        > Created Time: Mon 08 Jun 2015 09:55:51 AM CST
     ************************************************************************/
    
    //跟字符串相关的流:1)支持C风格的字符串流
    //                    2)支持C++风格的字符串流
    //    1 )    strstream (istrstrstream,    ostrstream)
    //    2 )    stringstream (istringstream, ostringstream)
    
    #include <iostream>
    #include <sstream>    
    #include <string>
    
    using namespace std;
    
    float str_to_float (const char * s) {
        istrstream tmp (s, strlen (s));
        float ans;
        tmp >> ans;
        return ans;
    }
    
    int main () {
    
        //想把整数输入到字符串里
        
        ostringstream oss;
        int i = 123;
        double d = 1.414;
    
        oss << i << '	' <<d;
        string str = oss.str ();
        
        cout << str << endl;
    
        //C++ 字符串
    
        istringstream iss ("223 2.414");
        iss >> i >> d;
        cout << i << '	'<< d << endl;
        
        //C 字符串
    
        char *s = "v  -3.1 // 3.1415";
        
    
        return 0;
    }

    在C语言中对输出的控制是非常方便的,同样,在C++中也可以对输出作格式控制,并且功能更加强大

    在控制格式上有两种方法: (1)使用 setfs 等控制符

                 (2)cout 的时候使用操作值

    /*************************************************************************
        > File Name: Code07.cpp
        > Author: Jeremy Wu
        > Created Time: Mon 08 Jun 2015 09:46:45 AM CST
     ************************************************************************/
    
    //流的输入输出的格式化
    // 控制格式两种方式 1)使用 setfs 等控制符
    //                    2)cout 的时候使用操作值
    
    #include <iostream>
    
    using namespace std;
    
    //ios 是所有流的基类
    
    ios::fmtflags oldFlag = cout.flags ();
    
    int main () {
    
        int i = 47;
        cout.setf (ios::showpos);    //显示正负号
        cout << i << endl;
        cout.setf (ios::showbase);    //显示进制号    
        //16进制输出
        cout << hex << i << endl;
        //8进制输出
        cout << oct << i << endl << endl;
        
        cout.flags (oldFlag);
    
        //默认保留6位数字
        double f = 1234.56789;
        cout << "default: 	" << f << endl;
        
        //科学计数法,默认保留小数后6位数字
        cout.setf (ios::scientific, ios::floatfield);
        cout << "scientific: 	" << f << endl;
                                                        
        //固定点模式,默认保留小数后6位数字
        cout.setf (ios::fixed, ios::floatfield);
        cout << "fixed: 	 " << f << endl;
    
        //恢复默认值
        cout.setf (ios::fmtflags (0), ios::floatfield);
        cout << "default: 	" << f << endl << endl;
        
        //输出浮点数默认精度
        cout << "default precision is " << cout.precision () << endl;
    
        //修改默认精度
        cout.precision (8);
    
        cout << "after precision (8)" << endl;
        cout << "default: 	" << f << endl;
        
        cout.setf (ios::scientific, ios::floatfield);
        cout << "scientific: 	" << f << endl;
    
        cout.setf (ios::fixed, ios::floatfield);
        cout << "fixed: 	" << f << endl << endl;
    
        cout.flags (oldFlag);
    
        //输出预留宽度        
        cout << "Current  	" << cout.width ()
            << "	 Currend fill character : 	" << cout.fill () << endl;
        
        cout.precision (6);
    
        //设置预留宽度
        //设置填充为 # 
        //默认按右边对齐
        //
        //    ·修改 width 只针对下一次输出有效
        //
        cout.width (20);
        cout.fill ('#');
    
        cout << f << endl;
        
        cout << "Current  	" << cout.width ()
            << "	 Currend fill character : 	" << cout.fill () << endl;
    
        cout << f << endl << endl;
    
        cout.width (20);
        cout << -f << endl;
        cout.width (20);
    
        //左边对齐
        cout.setf (ios::left, ios::adjustfield);
        cout << -f << endl;
        cout.width (20);
        
        //中间对齐
        cout.setf (ios::internal, ios::adjustfield);
        cout << -f << endl << endl;
    
        cout.flags (oldFlag);
    
        return 0;
    }

    在C++ 中有个非常有用的功能叫做模板 Template

    以下是一个 Template 简短 的例子

    在自己写模板的时候得注意许多小细节,比较在类的外部定义函数的时候需要在前面加上模板头还要在类后面加上<T>等

    /*************************************************************************
        > File Name: Code08.cpp
        > Author: Jeremy Wu
        > Created Time: Mon 08 Jun 2015 09:51:33 AM CST
     ************************************************************************/
    
    //函数模板
    //实例化的真正含义: 函数模板 -> 模板函数
    
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    /*
    int sum (int a, int b) {
        return a + b;
    }
    
    double sum (double a, double b) {
        return a + b;
    }
    */
    
    //模板的定义
    template <typename T>    //template head
    T sum (T _a, T _b) {
        return _a + _b;
    }
    
    //模板变量和模板常量(可以提供默认值
    template <typename T = double, int Size = 45>
    class Array {
    private:
        //const static int Size = 100;
        T a[Size];
    public:
        Array () { memset (a, 0, sizeof (a)); }
        T & operator [] (int index);
        Array & operator + (T rhs) {
            for (int i = 0; i < Size; ++i) a[i] += rhs;
            return *this;
        }
    };
    
    //在类的外部定义的时候
    //    1)加模板头
    //    2)类后面加 <T>
    template <typename T, int Size>
    T & Array <T, Size>::operator [] (int index) {
        if (index < 0 || index >= Size) {
            cout << "out of range" << endl;
            //exit (0);
        } else {
            return a[index];
        }
    
    }
    
    int main () {
        
        //模板的实例化 : 显示实例化 和 隐示实例化
        /*
        int i (10), j (7);
        cout << sum (i, j) << endl;
    
        double d1 (12.3), d2 (7.9);
        cout << sum <int> (d1, d2) << endl;
        */
    
        //Array <double, 100> ay;
        Array <>ay;
        ay[41] = 42;
        cout << ay[41] << endl;
    
        ay = ay + 5.2;
        cout << ay[41] << endl;
    
        return 0;
    }

    接下来是异常处理

    需要正确理解在异常处理整个周期中流程

    catch (...) // ... 可以捕捉任何类型的异常,并且这句 catch 必须放在所有 catch 的最后

    /*************************************************************************
        > File Name: Code10.cpp
        > Author: Jeremy Wu
        > Created Time: Mon 08 Jun 2015 11:44:31 AM CST
     ************************************************************************/
    
    //异常处理: exception handling
    //try  throw  catch
    //要理解异常处理的执行顺序
    
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class ExcepClass {
    public:
        string message () { return "devide number is invalid"; }
    };
    
    double devide (int a, int b) {
        if (0 == b)    throw ExcepClass ();    //如果符合条件,函数结束,所有局部变量释放
        cout << "Just after throw" << endl;
        return double (a) / b;
    }
    
    int main () {
    
        cout << "Before exception" << endl;
    
        try {
            int i (80), j (0);
            cout << devide (i, j) << endl;
            
            //出现异常以后的所有代码都不会被执行
            cout << "After devide (i, j)" << endl;
        }
        
        catch (ExcepClass k) {    //类型必须匹配捕捉到的类型
            cout << k.message () << endl;
        }
        
        catch (int m) {
    
        }
        catch (...) {    //捕捉任何类型的异常,并且...必须放在最后
            cout << "Captur all exception" << endl;
        }
        
        //结束异常处理
        cout << "After capture processing" << endl;
    
        return 0;
    }

    至此,一系列上课笔记

    END

  • 相关阅读:
    抽取一个简单的按钮方法
    一些iOS笔试题目
    使用第三方框架 Masonry 实现自动布局
    AutoLayout适配
    iOS面试小题集锦
    大牛们的技术博客
    5、过滤流
    3、过滤文件夹
    1、File类简介
    贪婪模式和非贪婪模式
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/4560769.html
Copyright © 2020-2023  润新知