• Union的妙用和注意


    一块内存不同的访问方式

    // 1.数组的便捷访问
    // 一块内存两种等价的访问方式
    template <typename T>
    union Mat4x4 {
        struct{
            T m00, m01, m10, m11;
        };
        T m[2][2];
    };
    
    int main(int argc, const char * argv[])
    {
        Mat4x4<float> mat = {1,2,3,4};
    
        std::cout<< mat.m00 <<std::endl;
        std::cout<< mat.m[0][0] <<std::endl;
        // output:  1
        //          1
        return 0;
    }

    将变量拆成字节访问

    int main(int argc, const char * argv[])
    {
        union Int4 {
            struct {
                unsigned char _1, _2, _3, _4;
            };
            int _int;
        };
        
        Int4 integer;
        integer._int = 100000000;
        printf("%08X
    ", integer._int);
        printf("%02X
    ", integer._1);
        printf("%02X
    ", integer._2);
        printf("%02X
    ", integer._3);
        printf("%02X
    ", integer._4);
        // output:
    //    05F5E100
    //    00
    //    E1
    //    F5
    //    05
        return 0;
    }

    判断CPU大小端问题

    int big_endian (void)
    {
        union{
            long l;
            char c[sizeof(long)];
        }u;
        
        u.l = 1;
        return (u.c[sizeof(long) - 1] == 1);
    }
    
    int main(int argc, const char * argv[])
    {
        //在大端格式中,字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中
        //与大端存储格式相反,在小端存储格式中,低地址中存放的是字数据的低字节,高地址存放的是字数据的高字节
        if(!big_endian()) {
            printf("CPU是小端模式
    ");
        }
        else {
            printf("CPU是大端模式
    ");
        }
    }
    // 这样判断大小端更简洁
    bool is_big_endian(void)
    {
        unsigned int test = 0xff000000;
        return (*(unsigned char *)&test == 0xff);
    }

     Union的内存占用

    首先内存占用肯定是要大于最大的一项,其次因为内存对齐的缘故

    int main(int argc, const char * argv[])
    {
        // # 内存问题
        union Max {
            char    _1;
            int     _4;
            double  _8;
            char    _17[17];
        };
        
        printf("size: %lu
    ", sizeof(Max));
        // output: size: 24
        
        return 0;
    }

    使用注意

    Union是C语言的东西,当然C++中也会有了,但是Union在C++中有些需要注意的地方。

    由于union里面的东西共享内存,所以不能定义静态、引用类型的变量。

    下面是错误的代码:

    union Test {
        static int c;
        int &ref;
    };

    C语言中没有类的概念,更没有构造和析构函数,Union中如果存在C++对象,那么C++对象必须不能存在构造和析构函数,

    默认的构造和析构不会被调用,存C++对象指针是没问题的。

    union TestUnion {
        
        class {
        public:
        //去掉注释会发生错误
        //TestClass() {
        //    printf("构造
    ");
        //}
        //~TestClass() {
        //    printf("析构
    ");
        //}
            
            int var;
        } c;
        
    };
            
    int main(int argc, const char * argv[])
    {
        TestUnion t = {1};
        printf("var: %d
    ", t.c.var);
        return 0;
    } 

    所以,我们在C++中使用union时,尽量保持C语言中使用union的风格,尽量不要让union带有对象。

  • 相关阅读:
    Java开发桌面程序学习(12)——Javafx 悬浮窗提示 tooptip
    Java开发桌面程序学习(11)——javafx 鼠标点击,右击,双击
    Web前端—— JQuery迷你版实现以及使用
    Web前端——表单提交和Js添加选项
    Web前端——JavaScript练习
    Web前端——JavaScript笔记
    <亲测>CentOS7中使用yum安装Nginx的方法
    Linux 软件安装到 /usr,/usr/local/ 还是 /opt 目录?
    <亲测>centos安装 .net core 2.1
    <亲测>CentOS7 安装mysql8.0(YUM方式)
  • 原文地址:https://www.cnblogs.com/luweimy/p/4119561.html
Copyright © 2020-2023  润新知