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

在我们学习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语言中强转可以成功,但是如果强转后,去访问有可能会访问越界。

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; // 这是因为单参数支持隐式类型转换
}

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

猜你喜欢

转载自blog.csdn.net/gangstudyit/article/details/80743370