菜鸟学习历程【33】类型转换、异常

类型转换

在 c语言 中,类型转换时很简单的,大致分为两种:
1.隐式转换

char c = 'A';
int  a = c;  // a = 65

2.强制转换

double d = 1.2;
int a = (int) d; // 丢失小数部分

这会导致两个问题的出现:
1)任何类型之间都可以转换,编译器很难判断正确性;
2)在源码中无法快速定位所有使用强制类型转换的语句;

因此,在程序设计理论中,强制类型转换不被推荐,与 goto 语句一样,应当 尽量避免。

C++ 提供了四种类型转换:
1. static_cast;
2. reinterpret_cast;
3. dynamic_cast;
4. const_cast

static_cast

普通数据类型转换,父子类指针的转换,在编译时进行,无法动态识别类型,不能用于基本类型指针的转换。

#include <iostream>

using namespace std;

class Animal
{
public:
    Animal()
    {

    }
    virtual void sleep()
    {
        printf("动物在睡觉\n");
    }
private:
    int age;
    char *name;
};

class Cat :public Animal
{
public:
    Cat()
    {

    }
    void sleep()
    {
        printf("猫 趴着睡觉\n");
    }
};

int main()
{
    int a = 2;
    double d = 1.2;
    char c = 'A';

    a = static_cast<int>(c);
    cout << "a = " << a << endl;

    d = static_cast<double>(a);
    cout << "d = " << d << endl;

    Animal *p = new Animal;
    Cat *pc = new Cat;

    // static_cast也可以实现父子类之间的转换,两个不相干的类,无法进行转换
    p = pc;
    p = static_cast<Animal *>(pc);

    return 0;
}

reinterpret_cast

用于指针类型的强制类型转换,用于整数和指针类型之间的强制类型转化(并不安全,不推荐使用)

#include <iostream>

using namespace std;

int main()
{
    int a = 5;
    int *pa = reinterpret_cast<int *>(&a); // 值的复制
    cout << "*pa = " << *pa << endl; // *pa = 5

    int tmp;         // 将数值转化为指针
    scanf_s("%x", &tmp);
    pa = reinterpret_cast<int *>(tmp);
    *pa = 10;
    cout << "a = " << a << endl;  // a = 10

    return 0;
}

dynamic_cast

实现动态转换,如果转换成功,返回指向该类的指针,否则 返回NULL;

#include <iostream>

using namespace std;

class Animal
{
public:
    Animal()
    {

    }
    virtual void sleep()
    {
        printf("动物在睡觉\n");
    }
private:
    int age;
    char *name;
};

class Cat :public Animal
{
public:
    Cat()
    {

    }
    void sleep()
    {
        printf("猫 趴着睡觉\n");
    }
    void CatchM()
    {
        printf("猫 捉老鼠\n");
    }
};

class Fish :public Animal
{
public:
    Fish()
    {

    }
    void sleep()
    {
        printf("鱼 睁着眼睡\n");
    }
    void Bubble()
    {
        printf("鱼 吐泡泡\n");
    }
};

void func1(Animal *p)
{
    p->sleep();

    Cat *pa = dynamic_cast<Cat *>(p);   //转换成 Cat 类型的指针
    if (pa != NULL)
    {
        pa->CatchM();
    }

    Fish *pf = dynamic_cast<Fish *>(p);  //转换成 Fish 类型的指针
    if (pf != NULL)
    {
        pf->Bubble();
    }
}

int main()
{
    Animal *p = new Animal;
    Cat *pc = new Cat;
    Fish *pf = new Fish;
    func1(p);
    func1(pc);
    func1(pf);

    return 0;
}

const_cast

将 const 常量 转换为 为一个非 const 常量
转换:将一个 变量 按某种方式 赋给 另一个变量,原来变量的属性不变;

#include <iostream>

using namespace std;

void func2(const char* ptr)
{
    char *str = const_cast<char *>(ptr);
    str[0] = 'w';
    ptr = "shanghai";
    cout << str << endl;
    cout << ptr << endl;
}

int main()
{
    //char *ptr = "hello world";    // 常量
    char ptr[] = "hello world";     // 使用数组时,在栈上开辟的空间来存放“hello world”,因此,可以修改
    func2(ptr);

    char* str[] = { "hello", "world" }; // 本质还是常量,常量放在代码段上,无法修改
    //func2(str[0]);
    return 0;
}

异常

1.异常是一种程序控制机制,与函数机制独立和互补
函数是一种以栈结构展开的上下函数衔接的程序控制系统,异常是另一种控制结构,它依附于栈结构,却可以同时设置多个异常类型作为网捕条件,从而以类型匹配在栈机制中跳跃回馈.

2.异常设计目的
栈机制是一种高度节律性控制机制,面向对象编程却要求对象之间有方向、有目的的控制传动,从一开始,异常就是冲着改变程序控制结构,以适应面向对象程序更有效地工作这个主题,而不是仅为了进行错误处理。

这里写图片描述

语法

// 捕获并处理异常的程序段
try
{
}
catch(异常类型声明)
{
    复合语句
}
catch(异常类型声明 (形参))
{
    复合语句
}
catch(...)  // 表示其他异常
{
    复合语句
}
// 抛掷异常的程序段
void func()
{
    throw 表达式;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值