C++学习七:异常处理、转换函数、智能指针

发布时间:2023年12月25日

一.异常处理

1.核心思想

? ? 让函数的设计者去检查错误,检查到错误时抛出异常,而函数的使用者捕获异常并处理异常

2.C++的异常处理机制有3部分组成:

? ? try(检查错误) -> throw(抛出异常) -> catch(捕获异常)

3.异常语法形式

? ? try{

? ? ? ? //检查错误

? ? ? ? if(错误)

? ? ? ? ? ? throw 异常

? ? }catch(异常1)

? ? {

? ? ? ? 处理异常

? ? }catch(异常2)

? ? {

? ? ? ? 处理异常

? ? }

? ? eg:? ? ? ?

 int divior(int x, int y)
? ? ? ? {
? ? ? ? ? ? if(y != 0)
? ? ? ? ? ? ? ? return x/y;                        //正确:返回结果
? ? ? ? ? ? else                                            //y == 0
? ? ? ? ? ? ? ? throw invalid_argument("invalid argument");//抛出异常
? ? ? ? }
? ? ? ? int main()
? ? ? ? {

? ? ? ? ? ? int m = 1;
? ? ? ? ? ? int n = 0;
? ? ? ? ? ? try{                                //检错
? ? ? ? ? ? ? ? cout << divior(m,n) << endl;
? ? ? ? ? ? }
            catch(const invalid_argument &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? } ?
? ? ? ? ? ? return 0;
? ? ? ? }

4.自定义异常

? ? eg1:由标准异常类派生? ? ? ?

class myexception : public exception{
? ? ? ? public:
? ? ? ? ? ? myexception(const char *str) noexcept : ptr(str) ?//指定异常不再抛异常
? ? ? ? ? ? {
? ? ? ? ? ?
? ? ? ? ? ? }
? ? ? ? ? ? ~myexception() noexcept //自动为序虚
? ? ? ? ? ? {
? ? ? ? ? ? }
? ? ? ? ? ? const char* what() const noexcept //重写基类的虚函数
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return ptr;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? const char *ptr;
? ? ? ? };
? ? ? ? int divior(int x, int y)
? ? ? ? {
? ? ? ? ? ? if(y != 0)
? ? ? ? ? ? ? ? return x/y;//正确:返回结果
? ? ? ? ? ? else if(0 == x)
? ? ? ? ? ? ? ? throw myexception("x == 0");//抛出自定义异常
? ? ? ? ? ? else//y == 0
? ? ? ? ? ? ? ? throw invalid_argument("invalid argument");//抛出标准异常
? ? ? ? }
? ? ? ? int main()
? ? ? ? {
? ? ? ? ? ? int m = 0;
? ? ? ? ? ? int n = 1;
? ? ? ? ? ? try
            {                //检错
? ? ? ? ? ? ? ? cout << divior(m,n) << endl;
? ? ? ? ? ? }
            catch(const invalid_argument &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? }
            catch(const myexception &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? } ? ? ?
? ? ? ? ? ? return 0;

? ? ? ? }

? ? ? ?

? ? eg2:不由标准异常类派生,自定义异常类? ? ?

? class myexception{
? ? ? ? public:
? ? ? ? ? ? myexception(const char *str) noexcept: ptr(str) ?//指定异常不再抛异常
? ? ? ? ? ? {
? ? ? ? ? ? }
? ? ? ? ? ? virtual ~myexception() noexcept //自动为序虚
? ? ? ? ? ? {
? ? ? ? ? ? }
? ? ? ? ? ? virtual const char* what() const noexcept //重写基类的虚函数
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return this->ptr;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? const char *ptr;
? ? ? ? };
? ? ? ? int divior(int x, int y)
? ? ? ? throw(invalid_argument)//指定函数可以抛出invalid_argument类型的异常
? ? ? ? {
? ? ? ? ? ? if(y != 0)
? ? ? ? ? ? ? ? return x/y;//正确:返回结果
? ? ? ? ? ? else if(0 == x)
? ? ? ? ? ? {
? ? ? ? ? ? #if 0
? ? ? ? ? ? ? ? throw myexception("x == 0");//抛出自定义异常
? ? ? ? ? ? #else
? ? ? ? ? ? ? ? myexception tmp("x == 0");
? ? ? ? ? ? ? ? throw tmp;
? ? ? ? ? ? #endif
            }
? ? ? ? ? ? else//y == 0
? ? ? ? ? ? ? ? throw invalid_argument("invalid argument");//抛出标准异常
? ? ? ? }
? ? ? ? int main()
? ? ? ? {
? ? ? ? ? ? int m = 0;
? ? ? ? ? ? int n = 1;
? ? ? ? ? ? try
            {//检错
? ? ? ? ? ? ? ? cout << divior(m,n) << endl;
? ? ? ? ? ? }
            catch(const invalid_argument &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? }
            catch(const myexception &iserr)//捕获异常
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? cout << iserr.what() << endl;//打印异常原因 处理异常
? ? ? ? ? ? } ? ? ?
? ? ? ? ? ? return 0;
? ? ? ? }

二.转换函数

1.目的

? ? 实现基本类型和自定义类型之间的转换;

2.语法形式

? ? operator 新类型() const

? ? {

? ? ? ? //转换语句

? ? }

? ? eg:

? ? ? ? operator int() const //自定义类型转int

? ? ? ? {

? ? ? ? }

? ? 注意:

? ? ? ? 转换函数只能是成员函数,无返回值,空参数。

? ? ? ? 不能定义到void的转换,也不允许转换成数组或者函数类型。

? ? ? ? 转换常定义为const形式,原因是它并不改变数据成员的值。

3.explicit关键字

? ? 阻止隐式类型转换;

? ? eg:? ? ? ?

class Demo{
? ? ? ? public:
? ? ? ? ? ? explicit Demo(int val) //explict:阻止隐式类型转换
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this->val = val;
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? ? ? virtual ~Demo()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? public:
? ? ? ? ? ? void setval(int val)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this->val = val;
? ? ? ? ? ? }
? ? ? ? ? ? int getval() const
? ? ? ? ? ? {
? ? ? ? ?? ? ? return this->val;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? int val;
? ? };
? ? int main()
? ? {
? ? ? ? Demo obj(666);
? ? ? ? obj = 123;//Demo tmp(123); obj = tmp; ? 隐式类型转换: int -> Demo
? ? ? ? cout << obj.getval() << endl;
? ? ? ? return 0;
? ? }

4.C++标准转换函数

? ? 编译时转换:reinterpret_cast、const_cast、static_cast

? ? 运行时候转换:dynamic_cast

? ?

? ? 1)reinterpret_cast

? ? ? ? 语法:reinterpret_cast<new type>(expression)

? ? ? ? 功能:将一个类型的指针转换为另一个类型的指针,它也允许从一个指针转换为整数类型

? ? ? ? eg:

? ? ? ? ? ? char *p;

? ? ? ? ? ? int *q;

? ? ? ? ? ? q = reinterpret_cast<int *> (p);//char * -> int *

? ? 2)const_cast

? ? ? ? 语法:const_cast< ?new type>( expression)

? ? ? ? 功能:const指针与普通指针间的相互转换,注意:不能将非常量指针变量转换为普通变量

? ? ? ? eg:

? ? ? ? ? ? const int *p;

? ? ? ? ? ? int *q;

? ? ? ? ? ? q = const_cast<int *>(p);//const int * -> int *

? ? ? ? ? ?

? ? 3)static_cast(普通类类型转换)

? ? ? ? 语法:static_cast<new type>(expression)

? ? ? ? 功能:主要用于基本类型间的相互转换,和具有继承关系间的类型转换

? ? ? ? eg:? ? ? ? ? ?

class Base{
? ? ? ? ? ? public:
? ? ? ? ? ? ? ? Base()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ~Base()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? };

? ? ? ? class Inherit : public Base{
? ? ? ? ? ? public:
? ? ? ? ? ? ? ? Inherit()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ~Inherit()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? };
? ? ? ? int main()
? ? ? ? {
? ? ? ? ? ? Base *p;
? ? ? ? ? ? Inherit *q;
? ? ? ? ? ? //p = q;//Inherit * -> Base *
? ? ? ? ? ? q = static_cast<Inherit *> (p); //Base * -> Inherit *
? ? ? ? ? ? return 0;
? ? ? ? }

? ? 4)dynamic_cast(有虚函数的类型转换)

? ? ? ? 语法:dynamic_cast<newtype>(expression)

? ? ? ? 功能:只有类中含有虚函数才能用dynamic_cast;仅能在继承类对象间转换

? ? ? ? 注意:dynamic_cast具有类型检查的功能,比static_cast更安全

? ? ? ? eg:? ? ? ? ? ?

class Base{
? ? ? ? ? ? public:
? ? ? ? ? ? ? ? Base()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ~Base()
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? }
? ? ? ? };
? ? ? ? ? ? class Inherit : public Base{
? ? ? ? ? ? ? ? public:
? ? ? ? ? ? ? ? ? ? Inherit()
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ~Inherit()
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ?cout << __func__ << ":" << __LINE__ ?<< endl;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? };
? ? ? ? ? ? int main()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Base *p;
? ? ? ? ? ? ? ? Inherit *q;
? ? ? ? ? ? ? ? //p = q;//Inherit * -> Base *
? ? ? ? ? ? ? ? q = dynamic_cast<Inherit *> (p); //Base * -> Inherit *
? ? ? ? ? ? ? ? return 0;
? ? ? ? ? ? }

5.自定义转换函数

? ? eg:? ? ?

? class Demo{
? ? ? ? public:
? ? ? ? ? ? explicit Demo(int val) : val(val)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? ? ? ~Demo()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? public:
? ? ? ? ? ? operator int() const //转换函数:Demo -> int
            {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? ? ? return this->val;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? int val;
? ? };
? ? int main()
? ? {
? ? ? ? Demo obj(666);
? ? ? ? int i;
? ? ? ? i = obj; //Demo -> int
? ? ? ? cout << "i=" << i << endl;
? ? ? ? return 0;

? ? }

三.智能指针

本质:类模板,模板中重载了->和*运算符。

1.shared_ptr指针

?

template <class T>
? ? class myshared_ptr{
? ? public:
? ? ? ? myshared_ptr(T *p) : ptr(p)
? ? ? ? {
? ? ? ? ? ? count ++;
? ? ? ? }
? ? ? ? myshared_ptr(const myshared_ptr<T> &obj)
? ? ? ? {
? ? ? ? ? ? cout++;
? ? ? ? }
? ? ? ? ~myshared_ptr()
? ? ? ? {
? ? ? ? ? ? count--;
? ? ? ? ? ? if(0 == count)
? ? ? ? ? ? ? ? delete ptr;
? ? ? ? }
? ? public:
? ? ? ? operator ->()//重载->运算符
        {
? ? ? ? }
? ? ? ? operator *() //重载*运算符
? ? ? ? {  }
? ? private:
? ? ? ? T *ptr;
? ? };

? ?

2.unique_ptr指针(独享指针)

? ? eg:? ? ? ?

 class Demo{
? ? ? ? public:
? ? ? ? ? ? explicit Demo(int val=0) :val(val)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }
? ? ? ? ? ? virtual ~Demo()
? ? ? ? ? ? {
? ? ? ? ? ? ? ? cout << __func__ << ":" << __LINE__ << endl;
? ? ? ? ? ? }

? ? ? ? public:
? ? ? ? ? ? void setval(int val)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? this->val = val;
? ? ? ? ? ? }

? ? ? ? ? ? int getval() const
? ? ? ? ? ? {
? ? ? ? ? ? ? ? return this->val;
? ? ? ? ? ? }
? ? ? ? private:
? ? ? ? ? ? int val;
? ? };
? ? int main()
? ? {
? ? ? ? unique_ptr<Demo> p(new Demo);//构造对象p
? ? ? ? //unique_ptr<Demo> pp = p;//禁止拷贝构造
? ? ? ? p->setval(666);//等价:(*p).setval(666);
? ? ? ? cout << p->getval() << endl;
? ? ? ? return 0;

? ? }

3.weak_ptr(弱指针)

? ? 通常配合共享指针进行操作;

文章来源:https://blog.csdn.net/only_write_bug/article/details/135197691
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。