C++ day8、day9 异常、转换函数、智能指针、STL标准模板库

一、异常的概念

概念:函数的设计者检查错误,并抛出异常,函数的使用者来捕获异常,处理异常

二、标准异常(if throw ; try catch(const invalid_argument & xxx){cout<<xxx.what()})

int divide(int x,int y){
    if (y == 0){
        throw("y==0!!!!!");
    }
    else 
        return x/y;
}

int main(){
    try{
        cout<<divide(5,0)<<endl;
    }catch(const invalid_argument & errmsg){
        cout<<errmsg.what()<<endl;
    }
    return 0;
}

三、自定义异常(由标准异常派生)

class Myexception: public exception{
    public:
        Myexception(const char *str) noexcept : ptr(str){

        }
        ~Myexception ()noexcept{
    
        }
    public:
        const char *what() const noexcept{        //重写基类的虚函数
            return ptr;            //throw("xxxxxxxx");  后续的错误语句就是这里的ptr
        }
    private:
        const char *ptr;
};

int divior(int x,int y){
    if (y!=0 && x!=0)
        return x/y;
    else if(x == 0)
        throw Myexception("x == 0!!");        //自定义派生异常
    else 
        throw invalid_argument("y == 0!!");    //标准异常
}

int main(){
    try{
        cout<<devior(0,0)<<endl;
    }catch(invalid_argument &xxxx){
        cout<<xxxx.what()<<endl;
    }catch(const Myexcepyion &xxxx){
        cout<<xxxx.what()<<endl;
    }

    return 0;
}

四、不由标准异常类派生,自定义异常类

		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.explicit关键字:阻止隐式类型转换(小的赋给大的,也叫小转大)

		class Demo{
        public:
            explicit Demo(int val) //explict:阻止隐式类型转换
            {
                this->val = val;

                cout << __func__ << ":" << __LINE__ << endl;
            }
         };

    int main()
    {
        Demo obj(666);

        obj = 123;//Demo tmp(123); obj = tmp;   隐式类型转换: int -> Demo

        cout << obj.getval() << endl;

        return 0;
    }

2.C++标准转换函数
    编译时转换:reinterpret_cast、const_cast、static_cast
    运行时候转换:dynamic_cast

2.1    1)reinterpret_cast
        语法:reinterpret_cast<new type>(expression)
        功能:将一个类型的指针转换为另一个类型的指针,它也允许从一个指针转换为整数类型

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

2.2    2)const_cast
        语法:const_cast<  new type>( expression)
        功能:const指针与普通指针间的相互转换,注意:不能将非常量指针变量转换为普通变量

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

2.3    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;
        }

2.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;
            }

2.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;
    }

六、智能指针

本质:类模板,模板中重载了->和*运算符(取内容)

解决:只malloc,而不去关心free

1. shard_ptr

	template <class T>
	class myshared_ptr{
	public:
		myshared_ptr(T *p) : ptr(p)
		{
			count ++;
		}
		myshared_ptr(const myshared_ptr<T> &obj)
		{
			count ++;
		}		
		~myshared_ptr()
		{
			count--;
			if(0 == count)
				delete ptr;
		}	
	public:
		operator ->()//重载->运算符
		{				
		}		
		operator *() //重载*运算符
		{		
		}	
	private:
		T *ptr;
	};
int main(){
		
			shared_ptr<Demo> p(new Demo);
			shared_ptr<Demo> pp = p;
    return 0;
}

2.unique_ptr指针(独享指针)

		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(弱指针)

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

int main()
{
	shared ptr<Demo> p(new Demo);//构造对象p
   weak_ptr<Demo> pp = p;//pp和p都指向Demo

   p.reset();//delete Demo
   
   if (pp.expired())
      cout<<"obj is not exist"<<endl;
}
	

七、STL模板库(了解程度有待提高)

STL的六个部分:容器 迭代器 算法 空间配置器 配接器 仿函数

STL序列容器:vector  --  动态数组        deque -- double-ended queue数组的头尾增删很快

                        list -- 双向链表

//vector向量
	相当于数组
	eg:
        int main()
        {
            int i = 0;
            list<int> a;//构造链表对象
            cout << a.size() << endl;

            for(i=0;i<5;i++) //头部插入节点
                a.push_front(i+1);

            for(i=0;i<5;i++)
                a.push_back(i+1);

            list<int>::const_iterator start = a.cbegin();//迭代器 获取第一个节点的指针
            for(i=0;i<a.size();i++)//遍历链表节点
            {   
                cout << *start << " ";
                start++;
            }   
            cout << endl;
            return 0;
        }

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值