C++ 类型转换全文超级详细的

目录

1 c语言中的类型转换

2. 为什么C++需要四种类型转换

3. C++强制类型转换

3.1 static_cast

3.2 reinterpret_cast

3.3 const_cast

3.4 dynamic_cast

4. RTTI(了解)

5. 常见面试题


1 c语言中的类型转换

        再c语言中,如果复制运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接受返回值 的类型不一样,就需要发生类型转换。C语言有两种类型转化,隐式类型转换或者显示类型转换。

#include<stdio.h>
#include<stdlib.h>
using namespace std;

void test01(){

    //隐式的类型转换
    int i=1;
    double d=i;
    printf_s("%d,%.2f\n",i,d);

    //显示的强制类型转换
    int *p=&i;
    int address=(intptr_t) p;

    // int address=(int) p;
    printf("%dx,%d\n",p,address);



}







int main()
{

test01();



system("pause");
return 0;
}
缺陷:
转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换

2. 为什么C++需要四种类型转换

C 风格的转换格式很简单,但是有不少缺点的:
1. 隐式类型转化有些情况下可能会出问题:比如数据精度丢失
2. 显式类型转换将所有情况混合在一起,代码不够清晰,因此C++ 提出了自己的类型转化风格,注意 因为 C++ 要兼容 C 语言,所以 C++ 中还可以使用 C 语言的 转化风格

3. C++强制类型转换

标准 C++ 为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符: static_cast reinterpret_cast const_cast dynamic_cast

3.1 static_cast

static_cast 用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用 static_cast ,但它不能用于两个不相关的类型进行转换。
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;

void test01(){

    //隐式的类型转换
    int i=1;
    double d=i;
    printf_s("%d,%.2f\n",i,d);

    //显示的强制类型转换
    int *p=&i;
    int address=(intptr_t) p;

    // int address=(int) p;
    printf("%dx,%d\n",p,address);



}


void test02(){
    // static_cast

    double d=12.34;
    int a=static_cast<int> (d);

    cout<<a<<endl;

}




int main()
{

// test01();
test02();



system("pause");
return 0;
}

3.2 reinterpret_cast

reinterpret_cast 操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换
为另一种不同的类型。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

void test01()
{

    //隐式的类型转换
    int i = 1;
    double d = i;
    printf_s("%d,%.2f\n", i, d);

    //显示的强制类型转换
    int *p = &i;
    int address = (intptr_t)p;

    // int address=(int) p;
    printf("%dx,%d\n", p, address);
}

void test02()
{
    // static_cast

    double d = 12.34;
    int a = static_cast<int>(d);

    cout << a << endl;
}

void test03()
{

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

    // 这里使用static_cast会报错,应该使用reinterpret_cast
    // int *p=static_cast<int*> (a);
    int *p=reinterpret_cast<int *> (a);

}

int main()
{

    // test01();
    // test02();
    test03();

    system("pause");
    return 0;
}

3.3 const_cast

const_cast 最常用的用途就是删除变量的 const 属性,方便赋值
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

void test01()
{

    //隐式的类型转换
    int i = 1;
    double d = i;
    printf_s("%d,%.2f\n", i, d);

    //显示的强制类型转换
    int *p = &i;
    int address = (intptr_t)p;

    // int address=(int) p;
    printf("%dx,%d\n", p, address);
}

void test02()
{
    // static_cast

    double d = 12.34;
    int a = static_cast<int>(d);

    cout << a << endl;
}

void test03()
{

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

    // 这里使用static_cast会报错,应该使用reinterpret_cast
    // int *p=static_cast<int*> (a);
    int *p=reinterpret_cast<int *> (a);

}

void test04(){

    //const_cast
    const int a=10;
    int *p=const_cast<int*> (&a);
    cout<<*p<<endl;


}

int main()
{

    // test01();
    // test02();
    // test03();
    test04();

    system("pause");
    return 0;
}

3.4 dynamic_cast

dynamic_cast 用于将一个父类对象的指针 / 引用转换为子类对象的指针或引用 ( 动态转换 )
向上转型:子类对象指针 / 引用 -> 父类指针 / 引用 ( 不需要转换,赋值兼容规则 )
向下转型:父类对象指针 / 引用 -> 子类指针 / 引用 ( dynamic_cast 转型是安全的 )
注意:
1. dynamic_cast 只能用于父类含有虚函数的类
2. dynamic_cast 会先检查是否能转换成功,能成功则转换,不能则返回 0
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

void test01()
{

    //隐式的类型转换
    int i = 1;
    double d = i;
    printf_s("%d,%.2f\n", i, d);

    //显示的强制类型转换
    int *p = &i;
    int address = (intptr_t)p;

    // int address=(int) p;
    printf("%dx,%d\n", p, address);
}

void test02()
{
    // static_cast

    double d = 12.34;
    int a = static_cast<int>(d);

    cout << a << endl;
}

void test03()
{

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

    // 这里使用static_cast会报错,应该使用reinterpret_cast
    // int *p=static_cast<int*> (a);
    int *p=reinterpret_cast<int *> (a);

}

void test04(){

    //const_cast
    const int a=10;
    int *p=const_cast<int*> (&a);
    cout<<*p<<endl;


}

class A{

    public:
        virtual void f(){


        }



};


class B:public A{


};



void fun(A *pa){

    //dynamic_cast 会先检查是否转换成功
    B* pb1=static_cast<B*> (pa);
    B *pb2=dynamic_cast<B*> (pa);

    cout<<"pb1:"<<pb1<<endl;
    cout<<"pb2:"<<pb2<<endl;


}



void test05(){

    A a;
    B b;
    fun(&a);
    fun(&b);


}




int main()
{

    // test01();
    // test02();
    // test03();
    // test04();
    test05();

    system("pause");
    return 0;
}

 

注意
强制类型转换关闭或挂起了正常的类型检查 ,每次使用强制类型转换前,程序员应该仔细考虑是
否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用
域,以减少发生错误的机会。 强烈建议:避免使用强制类型转换。

4. RTTI(了解)

RTTI Run-time Type identifification 的简称,即:运行时类型识别。
C++ 通过以下方式来支持 RTTI
1. typeid 运算符
2. dynamic_cast 运算符
3. decltype

5. 常见面试题

1. C++ 中的 4 中类型转化分别是: _________ _________ _________ _________
2. 说说 4 中类型转化的应用场景。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值