IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++自学笔记(day8) -> 正文阅读

[C++知识库]C++自学笔记(day8)

七、异常

一个错误处理系统包含异常、标准错误码、错误日志记录以及监测系统

异常:
	一种容错机制
基本思想:
	让一个函数在发现了自己无法处理的错误时抛出(throw)一个异常,然后它的(直接或者间接)调用者能够处理这个问题。
	异常处理机制是一种比较有效的处理系统运行时错误的方法。
	C++针对异常处理提供了一种标准的方法,用于处理软件程序运行时的错误,并用于处理软件系统中可预知或不可预知的问题。
	这样就可以保证软件系统运行的稳定性与健壮性
C++的异常处理机制:
	由3部分组成:
		try(检查)throw(抛出)->catch(捕获)
异常处理的一般格式:
	try{
		//检查语句
		if(错误){
			throw异常
		}
	} catch(异常类型1){
		进行异常处理的语句1
	}
	...

1.标准异常

abnormal.cpp

#include <iostream>
#include <string.h>
#include <stdexcept>
using namespace std;
//C++中默认每一个函数都会抛出异常,但是不会指定抛出的异常类型
//所以函数设计者应该在函数声明和定义时都显式说明抛出的异常类型。throw(异常类型)
int func(int, int) throw(runtime_error);    //函数声明、定义都需要显式说明

int func(int x, int y) throw(runtime_error){     //显式说明该函数抛出的异常类型,方便函数使用者捕获
    if(y)   //检查错误
        return x/y;
    else{
        //throw invalid_argument("error, y=0"); 
        //抛出异常,携带错误信息,本质是抛出一个匿名对象,抛出之后函数立即结束
        runtime_error tmp("error, y=0");
        throw tmp;
    }
}
int main()
{
    int a, b;
CIN:
    cin >> a >> b;
    try{                                    //错误检查
        cout << func(a, b) << endl;
    //}catch(const invalid_argument &err){    //捕获异常,捕获之后给err,保存错误信息
    }catch(const runtime_error &err){
        cout << err.what() << endl;         //异常处理,打印错误信息
        if( strcmp(err.what(), "error, y=0") == 0 )
            goto CIN;
    }
    return 0;
}

abnormal.cpp

#include <iostream>
#include <string.h>
#include <stdexcept>
using namespace std;
//C++中默认每一个函数都会抛出异常,如果要说明该函数不会抛出异常,那么声明定义都使用throw()
//如果函数说明为不会抛出异常,那么内部强行抛出异常,会直接终止程序
//throw() 是C++旧标准
//noexcept 是C++11标准中的运算符
int func(int, int) noexcept;    //函数声明、定义都需要显式说明

int func(int x, int y) noexcept{     //显式说明该函数抛出的异常类型,方便函数使用者捕获
    if(y)   //检查错误
        return x/y;
    else{
        runtime_error tmp("error, y=0");
        throw tmp;
    }
}
int main()
{
    int a, b;
CIN:
    cin >> a >> b;
    try{                                    //错误检查
        cout << func(a, b) << endl;
    }catch(const runtime_error &err){
        cout << err.what() << endl;         //异常处理,打印错误信息
        if( strcmp(err.what(), "error, y=0") == 0 )
            goto CIN;
    }
    return 0;
}

2.自定义异常

MyException.cpp

#include <iostream>
#include <string.h>
#include <stdexcept>
using namespace std;
class MyException : public exception{
public:
    MyException(const char *) noexcept;
    virtual ~MyException() noexcept;
    const char* what() const noexcept;
private:
    const char *msg;
};

MyException::MyException(const char *errmsg) noexcept :msg(errmsg){  }
MyException::~MyException() noexcept{  }
const char* MyException::what() const noexcept{
    return msg;
}

int func(int x, int y) throw(MyException){
    if(y)
        return x/y;
    else{
        throw MyException("error, y=0");
    }
}

int main()
{
    int a, b;
CIN:
    cin >> a >> b;
    try{                                    //错误检查
        cout << func(a, b) << endl;
    }catch(const MyException &err){
        cout << err.what() << endl;         //异常处理,打印错误信息
        if( strcmp(err.what(), "error, y=0") == 0 )
            goto CIN;
    }
    return 0;
}

3.转换函数

ConversionFunctions.cpp

/*
类作为C++中的自定义类型,需要类型转换时,C++提供类型转换函数 (type conversion function):
	将一个类的对象转换成另一类型的数据
	转换函数应该声明在要转换的类体中
转换函数的实质:
	运算符重载,只是重载的运算符不是内置的运算符而是类名这个特殊的自定义类型
语法:
	operator 类型名(){
		实现转换的语句
	}
基本规则:
	转换函数只能是成员函数,无数据类型,空参数,有返回值。
	不能定义到void的转换,也不允许转换成数组或者函数类型。
	转换常定义为const形式,原因是它并不改变数据成员的值。
*/
#include <iostream>
using namespace std;
class Base{
public:
    Base(int);
    int GetValue();
    operator int() const;
private:
    int x;
};

Base::Base(int x):x(x){  }
int Base::GetValue(){ return x; }
Base::operator int() const{
    return x;
}

int main()
{
    Base obj(5);
    int a = 13;
    obj = a;            //将a隐式转换成Base类型==> obj = Base(a);
    cout << obj.GetValue() << endl;
    obj = 1;
    a = obj;            //==> a = obj.operator int();
    cout << a << endl;
    cout << obj << endl; //将obj转换为int 然后输出
    return 0;
}

ConversionFunctions.cpp

#include <iostream>
using namespace std;
class Base{
public:
    Base(int);
    int GetValue();
private:
    int x;
};

Base::Base(int x):x(x){  }
int Base::GetValue(){ return x; }

class Demo{
public:
    Demo(int);
    operator Base() const;
private:
    int x;
};

Demo::Demo(int x):x(x){  }
Demo::operator Base() const{
    return x;
}

int main()
{
    Base obj(5);
    Demo obj1(5);
    obj = obj1;             //==> obj = Base( obj1.operator Base() );
    cout << obj.GetValue() << endl;
    return 0;
}

4.explicit关键字

explicit.cpp

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
class Demo{
public:
    Demo(int);
    int GetValue();
private:
    int x;
};

Demo::Demo(int x):x(x){  }
int Demo::GetValue(){ return x; }

class Base{
public:
    explicit Base(int);
    int GetValue();
private:
    int x;
};

Base::Base(int x):x(x){  }
int Base::GetValue(){ return x; }

int main()
{
    //定义初始化 先将int隐式转换为类类型再进行初始化
    Demo obj = 6;
    cout << obj.GetValue() << endl;
    //Base obj1 = 4;    //错误 此处不能隐式转换,因为构造函数被explicit修饰
    Base obj(4);
    //obj = 5;
    obj = Base(5);      //可以显式转换
    return 0;
}

5.标准转换函数

StdConversionFunctions.cpp

/*
C++标准转换函数
	编译时转换: reinterpret_cast、 const_cast、 static_cast
	运行时候转换: dynamic_cast
reinterpret_cast<new type>( expression)
	将一个类型的指针转换为另一个类型的指针,它也允许从一个指针转换为整数类型
const_cast<new type>( expression)
	const指针与普通指针间的相互转换,注意:不能将非常量指针变量转换为普通变量
static_cast<new type>(expression)
	主要用于基本类型间的相互转换,和具有继承关系间的类型转换
dynamic_cast<new type>(expression)
只有类中含有虚函数才能用dynamic_cast;仅能在继承类对象间转换
dynamic_cast具有类型检查的功能,比static_cast更安全
*/
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
class Base{
public:
    Base(int);
private:
    int x;
};

Base::Base(int x):x(x){  }

class Subclass:public Base{
public:
    Subclass(int, int);
private:
    int x;
};

Subclass::Subclass(int x, int y):Base(y), x(x){  }

int main()
{
    char buf[12] = "aello world";
    int *p = reinterpret_cast<int *>(buf);
    cout << *p << endl;
    cout << char (*p) << endl;

    int q = reinterpret_cast<int>(buf);
    cout << q << endl;

    const char *str = "hello world";
    char *s = const_cast<char *>(str);

    Base obj1(2);
    Subclass obj2(3, 8);

    obj1 = obj2;
    //obj2 = static_cast<Subclass>(obj1);
    //使用static_cast可以将具有继承关系的基类指针转换为派生类指针,实现大范围赋值给小范围
    Subclass *m = static_cast<Subclass *>(&obj1);
    return 0;
}

6.智能指针

SharedPtr.cpp

#include <iostream>
#include <memory>
using namespace std;
#define pri() cout<<"Line: "<<__LINE__<<endl;

class Base{
public:
    Base(){ pri(); }
    ~Base(){ pri(); }
    void func(){ pri(); }
};

void test(){
    //shared_ptr<Base> 准备定义一个管理Base数据的智能指针,此处重载了*号运算符
    //p(new Base) 让指针p指向Base类型的堆区空间
    //当p指针的生命周期结束时,会自动回收堆区空间资源
    //shared_ptr<Base>p(new Base);
    //shared_ptr<Base>q = p; //定义一个智能指针,指向p所指的空间

    cout << "--------------" << endl;
    //make_shared 函数模板是在堆区开辟一个资源共享的区域,执行完会自动回收一次
    shared_ptr<Base>m = make_shared<Base>(Base());
    //此处重载了-> 运算符,以->访问成员
    cout << "--------------" << endl;
    shared_ptr<Base>p = m;
    p->func();
    m->func();
}

int main()
{
    test();
    return 0;
}

C++自学笔记(目录)

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-30 22:40:09  更:2021-07-30 22:40:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/27 21:04:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码