• 类型转换_异常处理机制


    C++四种类型转换

    static_cast

    C++静态类型转换,c语言隐式类型可以转换的,基本上都可以

    //语法:
    
    type a = static_cast<type>(b); //b不为type类型

    reinterpret_cast

    指针类型不可以这么转化;指针需要强制类型转换

    char* p1 = "hello";
    int* p2 = NULL;
    p2 = reinterpret_cast<int*>(p1);

    dynamic_cast

    用于继承中多态时候的类型识别,在子类对象传给父类指针后,可以对父类指针使用dynamic_cast进行向下类型转换

    Dog *pDog = dynamic_cast<Dog*>(base);
    if(pDog != NULL)
      {
    转换成功;
    }
    const_cast
    去除变量的只读属性(去除const属性)
    注意:实参是可读可写才行;
    通过字符数组是在堆中分配内存空间;
    而char*指向的字符串是字符串常量,不可改变。
    void printBuf(const char* p)
    {
      char* p1 = NULL;
      p1 = const_cast<char*>(p);
      p1[0] = 'z';          //通过类型转换就可以改变指针指向的内存空间的值
    }
      char buf[] = "afdasdf"; //栈 中分配内存
      printBuf(buf); // ok
      char *my_p = "fsjljsf"; //字符常量,在 全局数据区 ,本身就不能改变;
      printBuf(my_p); //error
    
    
      • 首先字符串是在静态常量区分配的内存,然后指针my_p在栈里分配的内存,然后将指针指向”abacd”所在的内存块。指针存放的是"fsjljsf"的地址,而这个地址所在内存是在静态常量区中,是不可改变的。
      • char buf[]数组是在栈中,数组栈中分配了内存,是局部变量,也就是说,由于char buf[]是分配了内存的,所以这里只是将"afdasdf"复制到char buf[]在栈中分配的内存中去,是可读可写的。这里就和指针区别出来了,指针是不分配内存的,指针指向的是一块静态常量区中的内存。 
    异常处理机制:

    发生异常后,跨函数,从throw直接到catch
    可能有异常:

    void divide(int x, int y)
    {
      if(y == 0)
      throw x;
    }
    
    //测试案例:
    try
    {
      divide(10,0);
    }
    catch(int e)
    
    cout<<"10除以"<< e << endl;
    //    throw; //接到异常不处理
    }

    处理了异常,程序就不终止。catch到异常,但继续抛出去,由程序自己报错处理,或者其他catch处理

    1、如有异常通过throw操作创建一个异常对象并抛掷;
    2、将可能抛出异常的程序段放在try中。
    3、try的保护段没有异常,try后catch不执行,直到try后跟随的随后一个catch后面的语句继续执行下去。
    4、catch子句按照try后顺序执行,捕获或继续抛出异常。
    5、未找到匹配,函数terminate将被自动调用,其缺省功能即调用abort终止程序;
    6、异常处理不了,通过最后一个catch,使用throw语法,向上仍。


    重点:
    构造函数没有返回类型,无法通过返回值来报告运行状态,所以只能通过一种非函数机制的途径,
    即:异常机制,来解决构造函数的出错问题!!!

    异常是严格按照类型匹配,不会隐式类型转换

    try
    {
      throw 'z';
    }
    catch(int e)
    {
      cout << "捕获int类型异常" << endl;
    }
    catch(...)
    {
      cout << "未知异常" << endl;
    }

    结论:
    1、C++异常处理机制使得 异常引发 和 异常处理不必在同一个函数,
    底层更注重解决具体问题,而不必过多考虑异常的处理,上层调用者可以
    在适当位置设置 对不同类型异常的处理
    2、异常时专门针对抽象编程中一系列错误处理的,C++不能借助函数机制,因为栈结构
    先进后出,依次访问,但异常处理要跳级处理,跨越函数

    栈解旋:(重要)
    异常被抛出后,从进入try起,到异常被抛掷前,这期间栈上的
    构造的所有对象都会被自动析构,析构顺序与构造相反
    这一过程叫,栈解旋

    异常变量的生命周期:

    从try到异常抛掷前,其中的对象会自动析构。
    三种类型: int char* 类对象
    char*主要是 常字符串()全局数据区
    抛出(无参)构造函数
    throw Text(); //要加()
    用 元素 来接 catch(Text e) //此时,调用拷贝构造函数,析构时,先析构拷贝出来的e,再执行返回的元素
    用 引用 来接 catch(Text &e)//同一个元素
    用 指针 来接 catch(Text *e) //接不到异常,因为抛出的是元素,异常机制严格按照类型匹配

    异常的层次结构:继承中的异常
    类A中包含其他判断len的类,类A的构造函数根据讨论抛掷异常,即包含的那些类的构造函数。
    这些类使用同一个基类size,catch时,使用类A的引用产生多态。

  • 相关阅读:
    BZOJ 2299 向量
    BZOJ 1237 配对
    BZOJ 2226 LCMSum
    BZOJ 1876 SuperGCD
    查漏补缺:C++STL简述(容器部分)
    查漏补缺:Linux进程与线程的区别
    码海拾遗:常用的其中排序算法
    码海拾遗:简述C++(一)
    码海拾遗:简单的链表类
    码海拾遗:位运算实现加减乘除
  • 原文地址:https://www.cnblogs.com/Lunais/p/5852874.html
Copyright © 2020-2023  润新知