c++类型转换和异常

c++类型转换

知识点1 静态类型转换(static_cast)

用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换
进行上行转换:用父类指针、引用指向子类空间(安全)
进行下行转换:用子类指针、引用指向父类空间(不安全)
在这里插入图片描述

#include <iostream>
using namespace std;

class Animal{
public:
    virtual void showData(){
        cout << "父类函数" << endl;
    }
};

class Cat: public Animal{
public:
    void showData(){
        cout << "子类函数" << endl;
    }
};

class Other{};

void test01(){
    //static_cast 作用于 基本类型
    char ch = 'a';
    double d = static_cast<double>(ch);
    cout<<"d = "<<d<<endl;

    //static_cast 作用于 自定义数据类型(结构体 类)
    //关系的类之间
    //上行转换 安全
    Animal *p1 = static_cast<Animal*>(new Cat());
    p1->showData();

    //下行转换 不全 容易越界
    Cat *p2 = static_cast<Cat*>(new Animal);
    p2->showData();
    
    // static_cast 不能作用域 不相关的类之间转换
    //Animal *p3 = static_cast<Animal *>(new Other);//err
}
int main(int argc, char *argv[])
{
    test01();
    return 0;
}

运行结果:
在这里插入图片描述

知识点2【动态转换dynamaic_cast】

#include <iostream>

using namespace std;

class Animal{
};

class Cat: public Animal{
public:
    void showData(){
        cout << "子类函数" << endl;
    }
};

class Other{};

void test02(){
    //static_cast 不支持基本类型
    char ch = 'a';
    //double d = dynamic_cast<double>(ch);//err


    //dynamic_cast 作用于 自定义数据类型(结构体 类)
    //关系的类之间
    //上行转换 安全
    Animal *p1 = dynamic_cast<Animal*>(new Cat());
    //dynamic_cast 下行转换 不全 容易越界
    //Cat *p2 = dynamic_cast<Cat*>(new Animal());//dynamic_cast不支持 不安全 的转换
    

    // dynamic_cast 不能作用域 不相关的类之间转换
    //Animal *p3 = static_cast<Animal *>(new Other);//err
}

int main(int argc, char *argv[])
{
    test02();
    return 0;
}

知识点3【常量转换const_cast】

//常量转换const_cast
void test03(){

    const int *p1 = new int(10);
    int *p2 = const_cast<int*>(p1);

    int *p3 = new int(20);
    const int *p4 = const_cast<const int *>(p3);

    //const_cast不支持非指针或引用的转换
    const int a = 100;
    //int b = const_cast<int>(a);//err

    int data = 100;
    //普通引用转换成常量引用
    int &data1 = data;
    const int &data2 = const_cast<const int &>(data1);
}

知识点4【重新解释转换reinterpret_cast】


#include <iostream>
using namespace std;

class Animal{
public:
    virtual void showData(){
        cout << "父类函数" << endl;
    }
};

class Cat: public Animal{
public:
    void showData(){
        cout << "子类函数" << endl;
    }
};

class Other{};


void test04(){
	
	//reinterpret_cast 不支持基本数据类型
	char ch='a';
	//double d = reinterpret_cast<double>(ch);//err

	//reinterpret_cast 支持 不相关的类型间转换
	Animal *p1 = reinterpret_cast<Animal *>(new Other);

	//上行转换
	Animal *p2 = reinterpret_cast<Animal *>(new Cat());

	//下行转换
	Dog *p3 = reinterpret_cast<Cat *>(new Animal());
}

c++异常

知识点1【异常的概述】

常见的异常:除0溢出,数组下标越界,所要读取的文件不存在,空指针,内存不足等等。
c++的异常一旦抛出 如果不捕获 该异常 程序直接退出。
1、C语言通过返回值 来判断 第一:容易忽略 第二:容易和正常的结果混淆

int myDiv(int a, int b){
    if(b == 0){
        return -1;
    }
    return a/b;
}

int main(int argc, char *argv[])
{
    int ret = myDiv(10,-10);
    if(ret == -1){
        cout << "程序异常" << endl;
    }else{
        cout << "程序正常" << endl;
    }
    return 0;
}

运行结果:
在这里插入图片描述
2、c++抛出异常 并捕获
抛出异常:throw
捕获异常:try…catch

#include <iostream>
#include<string>
using namespace std;

int myDiv(int a,int b)
{
    if(b == 0)
        return -1;//-1表示失败
    return a/b;
}

int myDiv01(int a,int b)
{
    if(b==0)
        throw 0;//抛出异常

    return a/b;
}

void test02()
{
    try{
        int ret = myDiv01(10,0);
        cout<<"ret = "<<ret<<endl;
    }
#if 1
    catch(int e)//只捕获 抛出是int类型的异常
    {
        cout<<"捕获到int类型异常 e = "<<e<<endl;
    }
#endif
    catch(float e)//只捕获 抛出是float类型的异常
    {
        cout<<"捕获到float类型异常 e = "<<e<<endl;
    }
    catch(char e)//只捕获 抛出是char类型的异常
    {
        cout<<"捕获到char类型异常 e = "<<e<<endl;
    }
#if 0
    catch(...)
    {
        cout<<"捕获到其他异常"<<endl;
    }
#endif

    cout<<"程序做其他事情"<<endl;
}

运行结果:
在这里插入图片描述

知识点2【栈解旋(unwinding)】

异常被抛出后,从进入try块起,到异常被抛出前,这期间在线上构造所有对象,都会被自动析构。析构的顺序于构造的顺序相反,这一过程称为栈的解旋(unwinding)。

#include <iostream>
#include<string>
using namespace std;

class Person{
private:
    string name;
public:
    Person(string name)
    {
        this->name = name;
        cout<<"Person "<<name<<"构造函数"<<endl;
    }
    ~Person()
    {
        cout<<"Person "<<name<<"析构函数"<<endl;
    }
};

void test03()
{
    try{

        Person ob1("00_德玛");
        Person ob2("01_小炮");
        Person ob3("02_小法");
        Person ob4("03_提莫");

        throw 10;
    }
    catch(int)
    {
        cout<<"捕获到int异常"<<endl;
    }
    cout<<"其他工作"<<endl;
}

运行结果:
在这里插入图片描述

知识点3【异常接口声明】

#include <iostream>
#include<string>
using namespace std;

void testFunc01()
{
    //函数内部可以抛出任何异常
    //throw 10;
    //throw 4.3f;
    //throw 'a';
    //throw "hehe";
    string ob="heihie";
    throw ob;
}

//只能抛出int char 异常
void testFunc02() throw(int,char)
{
    throw 3.14f;
}

//函数 不抛出任何异常
void testFunc03()throw()
{
    throw 10;//外部捕获 不到
}

void test04()
{
    try{
        testFunc03();
    }
    catch(int e)//只捕获 抛出是int类型的异常
    {
        cout<<"捕获到int类型异常 e = "<<e<<endl;
    }
    catch(float e)//只捕获 抛出是float类型的异常
    {
        cout<<"捕获到float类型异常 e = "<<e<<endl;
    }
    catch(char e)//只捕获 抛出是char类型的异常
    {
        cout<<"捕获到char类型异常 e = "<<e<<endl;
    }
    catch(char const *e)//只捕获 抛出是char *类型的异常
    {
        cout<<"捕获到char const *类型异常 e = "<<e<<endl;
    }
    catch(string e)
    {
        cout<<"捕获到string类型异常 e = "<<e<<endl;
    }
}

知识点4【异常的生命周期】

在这里插入图片描述
在这里插入图片描述
推荐这种方式:
在这里插入图片描述

知识点5【标准异常】

知识点6【cin的拓展】

1、cin.get获取一个字符,cin.getline获取带空格的字符串

#include <iostream>
#include<string>
using namespace std;

void test07(){
    int data = 0;
    cin >> data;
    cout << "data = " << data << endl;

    char ch;
    cin >> ch;
    cout << "ch = " << ch << endl;

    //获取一个字符
    char ch1 = 'd';
    ch1 = cin.get();
    cout<<"ch1 = "<<ch1<<endl;

    char name[128]="ddddd";
    cin>>name;//遇到空格 回车结束获取
    cout<<"name="<<name<<endl;

    char name2[128]="sss";
    cin.getline(name2,sizeof(name));//可以获取带空格的字符串
    cout<<"name = "<<name2<<endl;

}

int main(int argc, char *argv[])
{
    test07();
    return 0;
}

2、cin.ignore忽略 缓冲区的前 n个字符
在这里插入图片描述
3、cin.putback放回缓冲区
在这里插入图片描述
4、cin.peek偷窥
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值