zoukankan      html  css  js  c++  java
  • 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带有对象。

  • 相关阅读:
    什么是RESTFUL?REST的请求方法有哪些,有什么区别?
    post提交的数据有哪几种编码格式?能否通过URL参数获取用户账户密码
    什么是jsp?jsp的内置对象有哪些?
    Session和Cookie的区别
    全面系统讲解CSS工作应用+面试一步搞定
    CSS实例:翻转图片、滚动图片栏、打开大门
    【HTML5版】导出Table数据并保存为Excel
    通过HTML5的getUserMedia实现拍照功能
    Day 19: EmberJS 入门指南
    18个基于 HTML5 Canvas 开发的图表库
  • 原文地址:https://www.cnblogs.com/luweimy/p/4119561.html
Copyright © 2011-2022 走看看