欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c++ 中的类型转换(强制转换和隐式类型转换)

程序员文章站 2022-07-15 10:08:02
...

在我们学习c语言的时候,就知道强制类型转换和隐式类型的转换,但是在类型转换的过程中,很有可能一个不注意,容易出问题,这无疑是加大了,程序员的工作量,而且还检查很不好检查。

所以在c++ 中就对类型的转换做了一定的限制,但是实际中大多数人,是在学习了c 语言后才学习 c++ 语言所以就用了 c 语言中的类型转换方式,那么今天我们介绍一下 c++ 中类型转换的方式,他们都是通过类模板的方式实现

const_cast 把const强转成非const修饰

在 c 语言中强转是可以把一个不想关的类型都可以强转,但是这样就很容易出问题,如果我们用了const_cast 如果要把两个两个不相关的类型的const转到非const是不行的。这样就限制了出错的概率,,增强了代码的可读性,但是实际中,大多数还是喜欢采用c语言,但是我们必须得知道。

    const int i = 10;//在c++中这样编译器会优化为寄存器变量用volatile
    int* j = const_cast<int*>(&i); // const 与非 const 转换

static_cast 隐式类型转换

什么是隐式类型的转换,隐式类型转换,就像c语言中我们可以把一个整型 int 赋值给一个 float 这就是隐式类型的转换。
我们简单的写一个例子

void test()
{
    int i = 10;
    float j = i; // 在c语言中的隐式类型的转换

    // 用static_cast转换
    float j = static_cast<float>(i); 
}

这样写增强了代码的可读性

reinterpret_cast 不相关类型转换

这强制类型转换是就像 c语言中的强转。
我们举一个例子:

typedef void (* FUNC)();
int DoSomething (int i)
{
cout<<"DoSomething" <<endl;
return 0;
}
void Test ()
{
//
// reinterpret_cast可以编译器以FUNC的定义方式去看待 DoSomething函// C++不保证所有的函数指针都被一样的使用,所以这样用有时会产生不
确定的结果
//
FUNC f = reinterpret_cast< FUNC>(DoSomething );
f(); 
}

这样我们就把一个函数赋值,还可以调用。

dynamic_cast虚函数中的父类赋给子类的转化

dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或引用(动态
转换)
向上转型:子类对象指针->父类指针/引用(不需要转换)
向下转型:父类对象指针->子类指针/引用(用dynamic_cast转型是安全的)

这里用这种强转必须要虚函数的类,用dynamic_cast来转换父类付给子类的时候,有时候可以,有时候不行,这样用dynamic_cast 强转就会在转变的过程中去判断,如果可以把父类给子类就强转,如果不行就返回0.

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;
}
int main ()
{
    A a;
    B b;
    fun(&a);
    fun(&b);
    return 0;
}

c++ 中的类型转换(强制转换和隐式类型转换)
红色标记的是强转失败,因为把父类赋给子类失败。强转就会判断是否成功。
如果用c语言中强转可以成功,但是如果强转后,去访问有可能会访问越界。

explicit关键字

在强转中,对于单参数的构造函数,支持隐式类型的转换,所以当我们不需要隐式类型的转换的时候,我们就可以加上explicit关键字来防止,在构造函数的时候发生隐式类型的转换。
单参数的类构造函数的隐式类型转换。

class A
{
public :
    explicit A (int a)
    {
    cout<<"A(int a)" <<endl;
    }
    A(const A& a)
    {
    cout<<"A(const A& a)" <<endl;
    }
private :
    int _a ;
};
int main ()
{
    A a1 (1);
    // 隐式转换-> A tmp(1); A a2(tmp);
    A a2 = 1; // 这是因为单参数支持隐式类型转换
}

我们加上关键字后,用 = 来进行隐式类型转换,是编译不能通过的。
c++ 中的类型转换(强制转换和隐式类型转换)
如果我们不加就可以通过。