C++ | 深入剖析C++中的类型转换

目录

12--C++的类型转换

1、C语言中的类型转换

2、C++中的四种类型转换(区分C语言)

A、static_cast ->隐式类型转换

B、reinterpret_cast ->显式类型转换

C、const_cast ->const指针类型转换为普通指针

D、dynamic_cast ->将基类指针向下转型

3、RTTI(运行时类型识别)(RTTI-Run-time Type identification)

4、习题:

C++中的四种类型转换分别是哪些?

请说明这四种类型转换的应用场景。


12--C++的类型转换

类型转换是编程中常见的操作,它允许我们在不同的数据类型之间进行转换。在C++中,类型转换不仅关系到程序的正确性,还关系到程序的效率和安全性。本文将深入探讨C++中的类型转换机制,包括隐式类型转换、显式类型转换以及C++特有的强制类型转换。

1、C语言中的类型转换

在C语言中,类型转换分为隐式类型转换和显式类型转换两种。隐式类型转换由编译器自动完成,而显式类型转换则需要程序员手动指定。然而,C语言的类型转换存在一些问题,比如隐式类型转换可能导致数据精度丢失,而显式类型转换的不透明性使得跟踪错误的转换变得困难。

  1. 隐式类型转换(也称为自动类型转换):这是编译器自动进行的类型转换,通常发生在赋值、算术运算或者函数调用时。隐式类型转换遵循一定的规则,例如,当较小的数据类型赋值给较大的数据类型时,数据会自动转换以适应目标类型。例如,int 类型的数据赋值给 float 类型时,int 会被隐式转换为 float。但是,如果隐式转换会导致数据丢失或不兼容,编译器会报错。
  2. 显式类型转换(也称为强制类型转换或类型铸造):当程序员需要将一个类型的数据显式转换为另一个类型的数据时,可以使用这种转换。显式类型转换需要程序员在代码中明确指定,通过在变量前加上目标类型的括号来实现。例如,(float)intValueintValue 显式转换为 float 类型。显式类型转换可以是安全的,也可以是不安全的,这取决于转换的类型和数据值。

显式类型转换的一个例子是:

int a = 10;
double b;
b = (double)a; // 显式地将int类型的a转换为double类型

隐式类型转换的一个例子是:

int a = 10;
float b = a; // 隐式地将int类型的a转换为float类型

2、C++中的四种类型转换(区分C语言)

为了解决C语言类型转换可视性比较差的问题,C++引入了四种命名的强制类型转换操作符:static_castreinterpret_castconst_castdynamic_cast。这些操作符提供了更高的类型转换可视性,使得代码更加清晰和安全。

A、static_cast ->隐式类型转换

static_cast用于非多态类型的转换,即静态转换。它可以执行编译器隐式执行的任何类型转换,但不能用于两个不相关的类型之间。

double x = 3.1415926;
cout << (int)x << endl;
int a = static_cast(x); // static_cast对应隐式类型转换——数据的含义没有发生变化
cout << a << endl;
B、reinterpret_cast ->显式类型转换

reinterpret_cast允许对操作数的位模式进行低层次的重新解释,适用于将一种类型转换为另一种不同的类型。

//x = reinterpret_cast(a); // reinterpter_cast代表对应的类型含义发生变化 不能互用
//cout << x << endl;
int* p = reinterpret_cast(a); // reinterpret_cast对应强制类型转化
cout << p << endl;
C、const_cast ->const指针类型转换为普通指针

const_cast的主要作用是移除或添加变量的const属性,使得可以对原本不可修改的变量进行赋值操作。

volatile const double pi = x; // volatile声明避免pi被当作宏替换 值无法改变
double* _pi = const_cast(&pi); // const_cast对应const指针的转化 必须是指针!

*_pi *= 2;
cout << pi << endl; // pi通过_pi被同步改变了
D、dynamic_cast ->将基类指针向下转型

dynamic_cast用于将父类对象的指针或引用转换为子类对象的指针或引用,这是动态转换的一种形式。它在转换前会进行检查,确保转换的安全性。

易错1:dynamic_cast要求被转换的对象中必须有虚函数表(才能进行RTTI)

易错2:dynamic_cast转换的对象是——派生类对象被切片放入基类对象中,希望向下转型回派生类对象,如果直接对基类指针进行向下转型,dynamic_cast将返回nullptr(跟malloc一样,先进行检查再使用指针)

class A
{
public:
    virtual void base()
    {
        cout << "A()" << endl;
    }
};
class B : public A
{
public:

};

int main()
{
 /********************************************************************/
    A* pa = new A();
    B* pb = new B();
    A* p = pb; // 派生类发生截断
    //a = b;
    //a.base();
    // pb = (B*)pb; // 不安全 没有合法性检查 可能会越界访问派生类未开辟的空间
    p->base();
    B* pp = dynamic_cast(p);

    pp->base();
 /********************************************************************/

    return 0;
}
3、RTTI(运行时类型识别)(RTTI-Run-time Type identification)

C++通过typeid运算符、dynamic_cast运算符和decltype关键字来支持运行时类型识别。

RTTI允许程序在运行时获取对象的类型信息,这对于多态性和类型安全的转换至关重要。

4、习题:
C++中的四种类型转换分别是哪些?

答:static_castreinterpret_castconst_castdynamic_cast

请说明这四种类型转换的应用场景。
    • static_cast:用于非多态性类型转换,如基本数据类型之间的转换。
    • reinterpret_cast:用于位模式的重新解释,如指针类型之间的转换。
    • const_cast:用于修改对象的const属性,进行必要的赋值操作。
    • dynamic_cast:用于安全的向下转型,即从父类指针或引用转换到子类。

你可能感兴趣的:(C++,算法,c++,开发语言,类型转换,c语言,后端)