dynamic_cast & static_cast

本文通过具体的C++代码示例,详细介绍了C++中动态类型转换(dynamic_cast)与静态类型转换(static_cast)的区别及使用场景。展示了如何在继承关系中安全地进行类型转换,并解释了这些转换在编译期与运行期的不同行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码如下:

#include <iostream> 
#include <iterator>
#include <vector>
#include <algorithm>
#include <utility> 
#include <string> 
#include <string.h>
#include <stdio.h>
 
//不久就在工作中碰到了一个活生生的例子
/*
#if 0
    //不能一步到位,error: expected unqualified-id before '(' token
    //可能表达式过于复杂了,拆之
    fMYRTSPClient->(dynamic_cast<H264DecodeSink*>(fMYRTSPClient->fVideosink))->AttachInput(
        this,(SIG_CAP_LIVE555RTP)&CLive555Ipc::OnLive555RtpInput);
 
    #else  
    //拆开赋值,我们的H264DecodeSink有继承自live555 FileSink
    //live555 FileSink无AttachInput(),所以要强制转换FileSink-->H264DecodeSink
     
    fVideosink = fMYRTSPClient->fVideosink;
    fH264DecodeSink = dynamic_cast<H264DecodeSink*>(fVideosink);
    fH264DecodeSink->AttachInput(this,(SIG_CAP_LIVE555RTP)&CLive555Ipc::OnLive555RtpInput);
    #endif
 
*/
 
 
//上行转换(up-casting)与下行转换(down-casting)
 
using namespace std;
 
class CDummy
{
public:
    int i;
    int m_chn;
    int m_type;
};
 
class CDummy_dup
{
public:
    CDummy_dup(){};
    virtual ~CDummy_dup(){};
     
    void Init(int chn,int type)
    {
        chn = 88;
        type = 99;
    };
     
    virtual int Connect()
    {
        return 0;
    }
 
public:
    int m_chn;
    int m_type;
};
 
class CBase
{
public:
    CBase();
    virtual ~CBase();
 
    void Init(int chn,int type);
    virtual int Connect();
     
public:
    int m_chn;
    int m_type;
     
};
 
CBase::CBase()
#if 1
:m_chn(0x100)
,m_type(0x300)
#endif
{
    printf("line %d, CBase::CBase, ch(%d), type(%d)\n",
        __LINE__, m_chn, m_type);
 
}
CBase::~CBase()
{
 
}
 
void CBase::Init(int chn,int type)
{
    m_chn = chn;
    m_type = type;
}
 
int CBase::Connect()
{
    printf("line %d, CBase::Connect, ch(%d), type(%d)\n",
        __LINE__, m_chn, m_type);
}
 
 
class CDerived:public CBase
{
public:
    CDerived();
    virtual ~CDerived();
public:
    int Connect();
 
public:
    int GetId() const {return fid;};
     
private:
public:
    int fid;
};
 
CDerived::CDerived()
{
    printf("line %d, CDerived::CDerived, ch(%d), type(%d)\n",
        __LINE__, m_chn, m_type);
     
    fid = 0x1000 + m_chn + m_type;
}
CDerived::~CDerived()
{
 
}
 
int CDerived::Connect()
{
    printf("line %d, CDerived::Connect, ch(%d), type(%d)\n",
        __LINE__, m_chn, m_type);
}
 
class CExample
{
public:
    CExample();
    //virtual ~CExample();
 
public:
    void InitDown(CBase* base);
    void TestDown();
 
     
    void InitUp(CDerived* derived);
    void TestUp();
public:
    CBase*    m_pBase;
    CDerived* m_pDerived;
 
};
 
CExample::CExample()
{}
 
 
//DOWN
void CExample::InitDown(CBase* base)
{
    m_pBase = base;
}
 
 
void CExample::TestDown()
{
#if 1
    printf("line %d, CExample::TestDown dynamic_cast, ch(%d), type(%d), fid(0x%04x), 000\n",
        __LINE__,
        (dynamic_cast<CDerived*>(m_pBase))->m_chn,
        (dynamic_cast<CDerived*>(m_pBase))->m_type,
        (dynamic_cast<CDerived*>(m_pBase))->GetId());
#endif
 
 
#if 1
    printf("line %d, CExample::TestDown static_cast,  ch(%d), type(%d), fid(0x%04x), 111\n",
        __LINE__,
        (static_cast<CDerived*>(m_pBase))->m_chn,
        (static_cast<CDerived*>(m_pBase))->m_type,
        (static_cast<CDerived*>(m_pBase))->GetId());
#endif
 
#if 0   //can not make
    //错误: 从类型‘CBase*’到类型‘CDummy*’中的 static_cast 无效
 
    printf("line %d, CExample::TestDown static_cast err, ch(%d), type(%d), fid(0x%04x), 222\n",
        __LINE__,
        (static_cast<CDummy*>(m_pBase))->m_chn,
        (static_cast<CDummy*>(m_pBase))->m_type,
        (static_cast<CDummy*>(m_pBase))->GetId());
#endif
 
#if 0   //can make,运行时"段错误 (核心已转储)"
        //实际上CDummy至少要有一个virtual func
 
    printf("line %d, CExample::TestDown dynamic_cast err, ch(%d), type(%d), 333\n",
            __LINE__,
            (dynamic_cast<CDummy*>(m_pBase))->m_chn,
            (dynamic_cast<CDummy*>(m_pBase))->m_type);
#endif
 
#if 0   //can make,运行时"段错误 (核心已转储)"
 
    printf("line %d, CExample::TestDown dynamic_cast err, ch(%d), type(%d), 444\n",
            __LINE__,
            (dynamic_cast<CDummy_dup*>(m_pBase))->m_chn,
            (dynamic_cast<CDummy_dup*>(m_pBase))->m_type);
#endif
 
    //m_pBase说,您把我下放了,我只能局限行事了。
    //以下call CDerived::Connect()
 
    (static_cast<CDerived*>(m_pBase))->Connect();
    (dynamic_cast<CDerived*>(m_pBase))->Connect();
 
    //call GetId,表明m_pBase确实下放了。
    (static_cast<CDerived*>(m_pBase))->GetId();
     
}
 
 
//UP
void CExample::InitUp(CDerived* derived)
{
    m_pDerived = derived;
}
 
 
void CExample::TestUp()
{
#if 1
    printf("line %d, CExample::TestUp dynamic_cast, ch(%d), type(%d), fid(0x%04x), 000\n",
        __LINE__,
        (dynamic_cast<CBase*>(m_pDerived))->m_chn,
        (dynamic_cast<CBase*>(m_pDerived))->m_type,
        0);
        //(static_cast<CBase*>(m_pDerived))->GetId());
 
#endif
 
 
#if 1
    printf("line %d, CExample::TestUp static_cast,  ch(%d), type(%d), fid(0x%04x), 111\n",
        __LINE__,
        (static_cast<CBase*>(m_pDerived))->m_chn,
        (static_cast<CBase*>(m_pDerived))->m_type,
        0);
        //(static_cast<CBase*>(m_pDerived))->GetId());
#endif
 
#if 0   //can not make
        //错误: 从类型‘CDerived*’到类型‘CDummy*’中的 static_cast 无效
 
    printf("line %d, CExample::TestUp static_cast err, ch(%d), type(%d), fid(0x%04x), 222\n",
        __LINE__,
        (static_cast<CDummy*>(m_pDerived))->m_chn,
        (static_cast<CDummy*>(m_pDerived))->m_type,
        0);
        //(static_cast<CDummy*>(m_pDerived))->GetId());
#endif
 
#if 0   //can make,运行时"段错误 (核心已转储)"
        //实际上CDummy至少要有一个virtual func
 
        printf("line %d, CExample::TestUp dynamic_cast err, ch(%d), type(%d), 333\n",
            __LINE__,
            (dynamic_cast<CDummy*>(m_pDerived))->m_chn,
            (dynamic_cast<CDummy*>(m_pDerived))->m_type,
            0);
#endif
 
#if 0   //can make,运行时"段错误 (核心已转储)"
        printf("line %d, CExample::TestUp dynamic_cast err, ch(%d), type(%d), 444\n",
            __LINE__,
            (dynamic_cast<CDummy_dup*>(m_pDerived))->m_chn,
            (dynamic_cast<CDummy_dup*>(m_pDerived))->m_type);
#endif
 
    //m_pDerived说,您把我提升了,我就不客气按职位来行事了。
    //以下call CDerived::Connect()
    (static_cast<CBase*>(m_pDerived))->Connect();
    (dynamic_cast<CBase*>(m_pDerived))->Connect();
 
    //错误: ‘class CBase’没有名为‘GetId’的成员
    //此错误表明m_pDerived确实被提升了。
    //(static_cast<CBase*>(m_pDerived))->GetId();
    //(dynamic_cast<CBase*>(m_pDerived))->GetId();
}
 
/*
    从Test()可以看出,
    static_cast 编译期
    dynamic_cast    运行期
    至于up or down不是最关键的,关键的是pDesire和pConverted的关系
    是否合理。这个合理性则需要自己来保证了。
*/
 
int main (int argc,char *argv[])
{ 
    CExample *pExmp = new CExample();
 
    CBase *pBase = new CDerived();
    pBase->Init(1,3);
     
    printf("\nline %d, pBase->ch(%d), pBase->type(%d), 000\n\n",
        __LINE__, pBase->m_chn, pBase->m_type);
     
    pExmp->InitDown(pBase);
     
    pExmp->TestDown();
    printf("\nline %d, pBase->ch(%d), pBase->type(%d), 111\n\n",
        __LINE__, pBase->m_chn, pBase->m_type);
 
     
    printf("\nline %d, ######\n\n", __LINE__);
     
    CDerived *pDerived = new CDerived();
 
    pDerived->m_chn = 2;
    pDerived->m_type = 6;
    pDerived->fid= 0x1000 + pDerived->m_chn + pDerived->m_type;
 
    pExmp->InitUp(pDerived);
    pExmp->TestUp();
 
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值