C++ const void * 类型转换各种类型转换简单测试

这样转化是没有问题的。

int a{ 100 };
const void *p = &a;
const int *pi = static_cast<const int *>(p);
cout << *pi << endl;

输出:

100

void * 转换貌似原来什么类型,再强转回去没啥问题,动态类型和多继承好像有问题。


各类转换成测试

#define NS_BEGIN  namespace {
#define NS_END }

NS_BEGIN

struct CA
{
    string hi{ "你好" };
    int aNum{ 11 };
};

struct CB
{
    int bNum{ 22 };
    string hello{ "哈喽" };
};

struct CC
{
    double cNum_f{ 12.12 };
    int cNum_i{ 12 };
};

struct DObj :CA, CB, CC
{
    string self{ "D Obj" };
};



struct DY_CA
{
    virtual ~DY_CA() {}
    string hi{ "DY你好" };
    int aNum{ 11 };
};

struct DY_CB
{
    virtual ~DY_CB() {}
    int bNum{ 22 };
    string hello{ "DY哈喽" };
};

struct DY_CC
{
    virtual ~DY_CC() {}
    double cNum_f{ 12.12 };
    int cNum_i{ 12 };
};

struct DY_DObj :DY_CA, DY_CB, DY_CC
{
    string self{ "DY Obj" };
};


NS_END

int main()
{
    DObj dobj;

    // 下面三个数据转换没有问题,数据也正确
    DObj *pdobj = &dobj;
    CA *ca = static_cast<CA *>(pdobj);
    CB *cb = static_cast<CB *>(pdobj);
    CC *cc = static_cast<CC *>(pdobj);


    CA *sub_ca = &dobj;
    // 自己转自己,没有错误,数据也没错。
    CA *s_ca = static_cast<CA *>(sub_ca);

#if 0 // 下面两个报错:无效的转化  基类虚函数也不行
    CB *s_cb = static_cast<CB *>(sub_ca);
    CC *s_cc = static_cast<CC *>(sub_ca);
#else // 下面两个虽然编译器没报错,但转换出来的数据是错误的
    CB *s_cb = (CB *)(sub_ca);
    CC *s_cc = (CC *)(sub_ca);
#endif
    // 下面这个往原始类型转,数据没有问题。
    DObj *s_dobj = static_cast<DObj *>(sub_ca);


    // 从 void* 静态转化,编译器没报错,但转换的数据有问题,不正确。
    void *v_pdobj = &dobj;
    CA *v_ca = static_cast<CA *>(v_pdobj);
    CB *v_cb = static_cast<CB *>(v_pdobj);
    CC *v_cc = static_cast<CC *>(v_pdobj);
#if 0 // 下面三个,从 void * 动态转换,编译器报错,不允许。
    CA *dy_ca = dynamic_cast<CA *>(v_pdobj);
    CB *dy_cb = dynamic_cast<CB *>(v_pdobj);
    CC *dy_cc = dynamic_cast<CC *>(v_pdobj);
#endif

    // 原始对应的类型,静态强转数据没有问题。
    DObj *v_dobj = static_cast<DObj *>(v_pdobj);


    // 测试下动态的


    DY_DObj DY_dobj;

    // 下面三个数据转换没有问题,数据也正确
    DY_DObj *DY_pdobj = &DY_dobj;
    DY_CA *DY_ca = static_cast<DY_CA *>(DY_pdobj);
    DY_CB *DY_cb = static_cast<DY_CB *>(DY_pdobj);
    DY_CC *DY_cc = static_cast<DY_CC *>(DY_pdobj);



    DY_CA *DY_sub_ca = &DY_dobj;
    // 自己转自己,没有错误,数据也没错。
    DY_CA *DY_s_ca = static_cast<DY_CA *>(DY_sub_ca);

#if 0 // 下面两个报错:无效的转化  和上面没虚函数的一样也不能转换 编译器报错
    DY_CB *DY_s_cb = static_cast<DY_CB *>(DY_sub_ca);
    DY_CC *DY_s_cc = static_cast<DY_CC *>(DY_sub_ca);
#else //  和上面无 DY 前缀的一样, 下面两个虽然编译器没报错,但转换出来的数据是错误的
    DY_CB *DY_s_cb = (DY_CB *)(DY_sub_ca);
    DY_CC *DY_s_cc = (DY_CC *)(DY_sub_ca);
#endif
    // 和上面无 DY 前缀的一样,下面这个往原始类型转,数据没有问题。
    DY_DObj *DY_s_dobj = static_cast<DY_DObj *>(DY_sub_ca);

    // 动态转化,当然没毛病,数据正常
    DY_CB *DY_s_cb_dy = dynamic_cast<DY_CB *>(DY_sub_ca);
    DY_CC *DY_s_cc_dy = dynamic_cast<DY_CC *>(DY_sub_ca);
    DY_DObj *DY_s_dobj_dy = dynamic_cast<DY_DObj *>(DY_sub_ca);

    // 和上面无 DY 前缀的一样,从 void* 静态转化,编译器没报错,但转换的数据有问题,不正确。
    void *DY_v_pdobj = &DY_dobj;
    DY_CA *DY_v_ca = static_cast<DY_CA *>(DY_v_pdobj);
    DY_CB *DY_v_cb = static_cast<DY_CB *>(DY_v_pdobj);
    DY_CC *DY_v_cc = static_cast<DY_CC *>(DY_v_pdobj);
#if 0 // 和上面无 DY 前缀的一样, 下面三个,从 void * 动态转换,编译器报错,不允许。
    DY_CA *DY_dy_ca = dynamic_cast<DY_CA *>(DY_v_pdobj);
    DY_CB *DY_dy_cb = dynamic_cast<DY_CB *>(DY_v_pdobj);
    DY_CC *DY_dy_cc = dynamic_cast<DY_CC *>(DY_v_pdobj);
#endif

    // 和上面无 DY 前缀的一样, 原始对应的类型,静态强转数据没有问题。
    DY_DObj *DY_v_dobj = static_cast<DY_DObj *>(DY_v_pdobj);


    system("pause");
    return EXIT_SUCCESS;
}

总结

  1. void*或基类指针可以往原始派生类静态强转,数据没问题;接收什么数据类型,再静态强转回去没问题。
  2. 兄弟基类指针静态强转兄弟指针数据会有问题,指针接受的是什么类型,静态强转回去,没有问题。
  3. 派生类指针,静态强转为基类指针,数据没有问题。范围往小的转,貌似没有问题。
  4. 含虚函数的动态类型,dynamic_cast 各种动态强转,那是没问题的。
posted @   double64  阅读(57)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2021-09-22 C# 去掉字符串多余空格
2021-09-22 C# 统计字符出现次数
2021-09-22 C# 冒泡排序
2021-09-22 C# Math.Round()四舍五入
2021-09-22 C# 交换两个变量值
2021-09-22 英语|play
2021-09-22 C#.Net XML
点击右上角即可分享
微信分享提示