C++: Type conversions

1、static_cast

    static_cast可以转换相关联的类,可以从子类转换成父类。也能从父类转向子类,但是如果转换的父类指针(或者父类引用)所指向的对象是完整的,那么是没有问题;但是如果所指向的对象并不完整,那么会出现runtime错误。
    static_cast相对于dynamic_cast而言,除了能转换指针和引用,还能应用于任何能够隐式转换的情况。

 

2、const_cast
    const_cast如它的名字,它是去除修饰在对象上的const和volatile。

 

3、dynamic_cast
    我们从适用范围来了解这个操作。
    (1)首先dynamic_cast能够应用于指针转换。
    子类指针转换成父类指针,成功;
    父类指针转换成子类指针,就分为两种情况:
        <a>父类指针p如果真的指向子类对象,那么转换时成功的;
        <b>反之,失败,dynamic_cast返回NULL。
    (2)其次dynamic_cast能够应用与引用之间的转换(与指针类似)。
    子类引用转换成父类引用,成功;
    父类引用转换成子类引用,就分为两种情况:
        <a>父类引用ob,如果真的指向子类对象,那么转换时成功的;
        <b>反之,失败,dynamic_cast,会抛出bad_cast异常。
    (3)其他将null指针,转换成任何类型的指针;将任何类型的指针转换成void*类型的指针。

 

4、reinterpret_cast
    reinterpret_cast和上面讲到的两个cast,适用范围更加广泛。它可以适用于任何类型指针之间的转换。
    该操作不会去进行动态类型或者静态类型的检测,它仅仅将值强行赋值过去。从某种意义上对编译器进行了一种欺骗,同时也带来了一定的不安全性。所以在使用这个cast的时候,要慎重。下面是这个操作的适用情况:
    (1)int和指针之间的相互转换;
    (2)无关联类指针之间的转换;
    (3)函数指针之间的转换。

 

#include <iostream>


void test_static_cast()  
{  
    float f = 1.012;  
    int i = static_cast<int>(f); 

    std::cout << f << " " << i << std::endl; 
}


class CBase  
{  
protected:  
    int m_data;  

public:  
    virtual void fun() { }
};


class CSub1 : public CBase  
{  
protected:  
    int m_data_a;  
};


class CSub2 : public CBase  
{  
protected:  
    long m_data_b;  
};


void test_dynamic_cast()
{
    CBase * pb = new CBase();
    CSub1 * p1 = new CSub1();
   
    char strTrue[] = "true";
    char strFalse[] = "false";

    CBase * p = dynamic_cast<CBase*>(p1);
    std::cout << "dynamic_cast<CBase *>(p1); is ok? "<< ((p != NULL) ? "true" : "false") << std::endl;

    CSub1 * pSub1 = dynamic_cast<CSub1*>(pb);
    std::cout << "dynamic_cast<CSub1 *>(pb); is ok? "<< ((pSub1 != NULL)? "true" : "false") << std::endl;
   
    delete pb;
    delete p1;
 
    try
    {
        CBase obb;
        CSub1 obsub1;
        CBase& ob1 = dynamic_cast<CBase &>(obsub1);
        CSub1& ob2 = dynamic_cast<CSub1 &>(obb);
    }
    catch(std::bad_cast e)
    {
         
    }
}


class A  
{  
public:  
    A(int i)
    : m_data(i)
    {

    }

    int m_data;  
};


class B
{
public:
    B(float f)
    : m_data(f)
    {

    }

    float m_data;  
};


class C
{
public:
    C(long long ll)
    : m_date(ll)
    {

    }

    long long m_date;
};


void test_reinterpret_cast()  
{  
    A* pa = new A(1);  
    B* pb = new B(1.12);  
    C* pc = new C(121321312321);  
 
    A* p1 = reinterpret_cast<A*>(pb);  
    std::cout << "reinterpret_cast<A*>(pb); is ok? "<< ((p1 != NULL) ? "true": "false") << std::endl;  
    std::cout << p1->m_data << std::endl;  
    
    p1 = reinterpret_cast<A*>(pc);  
    std::cout << "reinterpret_cast<A *>(pc); is ok? "<< ((p1 != NULL) ? "true": "false") << std::endl;  
    std::cout << p1->m_data << std::endl;  
    
    delete pa;  
    delete pb;  
    delete pc;  
}


int main()
{
    test_static_cast();
    test_dynamic_cast();
    test_reinterpret_cast();

    return 0;
}

 

参考:

https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used/332086#332086

https://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast?noredirect=1&lq=1

https://www.quora.com/How-do-you-explain-the-differences-among-static_cast-reinterpret_cast-const_cast-and-dynamic_cast-to-a-new-C++-programmer

http://www.stroustrup.com/bs_faq2.html

http://www.cplusplus.com/doc/tutorial/typecasting/

 

posted @ 2016-08-08 11:43  朔方  阅读(236)  评论(0编辑  收藏  举报