张师睿 2024-05-06 16:03 采纳率: 0%
浏览 3

c++位域封装为class大小异常

我写了如下代码:


class one_bit{
    unsigned char b:1;
    public:
        one_bit():b(0){}
        one_bit(int x):b(x&1){}
            one_bit(unsigned int x):b(x&1){}
        one_bit(long x):b(x&1){}
        one_bit(unsigned long x):b(x&1){}
        one_bit(char x):b(x&1){}
        one_bit(unsigned char x):b(x&1){}
        one_bit(long long x):b(x&1){}
            one_bit(unsigned long long x):b(x&1){}
        one_bit(one_bit& b2){
            b=b2.b;
        }
        one_bit(one_bit&& b2){
            b=b2.b;
        }
        template<typename T>
        one_bit(T x):b(x%2){}
        one_bit operator= (one_bit b2){
            b=b2.b;
            return *this;
        }
        operator int()const{return int(b);}
        operator unsigned int()const{return (unsigned int)(b);}
        operator char()const{return char(b);}
        operator unsigned char()const{return (unsigned char)(b);}
        operator long()const{return long(b);}
        operator unsigned long()const{return (unsigned long)(b);}
        operator long long()const{return (long long)(b);}
        operator unsigned long long()const{return (unsigned long long)(b);}
}bits[8];

我期望bits数组总大小我1字节,即8个1位的位域,但实际情况是每个one_bit对象每个一个字节,谁给我把他们放到一个字节里

  • 写回答

5条回答 默认 最新

  • 关注

    晚上好🌙🌙🌙
    本答案参考ChatGPT-3.5

    经过测试,发现每个one_bit对象的大小确实是一个字节,但是因为C++有对齐要求,导致编译器为了对齐,会在编译过程中自动为结构体或类的每个成员加上一些不必要的填充字节,因此8个one_bit对象会占用8个字节,而不是1个字节。

    解决方法:

    1. 使用一个字节作为成员变量而不是位域,自己控制位的具体值。由于C++对齐的要求是基于数据类型的大小来决定的,所以如果我们使用一个字节类型的成员变量,它就只会占用一个字节的内存,而不会因为对齐而占用多余的内存。

    代码示例:

    class one_bit{
        unsigned char byte;
    public:
        one_bit():byte(0){}
        one_bit(int x):byte(x&1){}
        one_bit(unsigned int x):byte(x&1){}
        one_bit(long x):byte(x&1){}
        one_bit(unsigned long x):byte(x&1){}
        one_bit(char x):byte(x&1){}
        one_bit(unsigned char x):byte(x&1){}
        one_bit(long long x):byte(x&1){}
        one_bit(unsigned long long x):byte(x&1){}
        one_bit(one_bit& b2){
            byte = b2.byte;
        }
        one_bit(one_bit&& b2){
            byte = b2.byte;
        }
        template<typename T>
        one_bit(T x):byte(x%2){}
        
        one_bit operator= (one_bit b2){
            byte = b2.byte;
            return *this;
        }
    
        operator int()const{return int(byte);}
        operator unsigned int()const{return (unsigned int)(byte);}
        operator char()const{return char(byte);}
        operator unsigned char()const{return (unsigned char)(byte);}
        operator long()const{return long(byte);}
        operator unsigned long()const{return (unsigned long)(byte);}
        operator long long()const{return (long long)(byte);}
        operator unsigned long long()const{return (unsigned long long)(byte);}
    };
    
    one_bit bits[8];
    
    1. 使用pragma指令取消对齐优化。在类定义前加上#pragma pack(n),其中n是对齐字节数,这里设置为1,表示1字节对齐。这种方法需要注意,在取消对齐优化后,如果一个结构体或类有多个成员变量,它们的内存布局可能不再按原来的顺序排列,而是按照它们在代码中的声明顺序排列,这可能会导致代码不可移植或存在潜在的内存访问错误,慎用。

    代码示例:

    #pragma pack(1)
    class one_bit{
        unsigned char b:1;
    public:
        one_bit():b(0){}
        one_bit(int x):b(x&1){}
        one_bit(unsigned int x):b(x&1){}
        one_bit(long x):b(x&1){}
        one_bit(unsigned long x):b(x&1){}
        one_bit(char x):b(x&1){}
        one_bit(unsigned char x):b(x&1){}
        one_bit(long long x):b(x&1){}
        one_bit(unsigned long long x):b(x&1){}
        one_bit(one_bit& b2){
            b=b2.b;
        }
        one_bit(one_bit&& b2){
            b=b2.b;
        }
        template<typename T>
        one_bit(T x):b(x%2){}
        
        one_bit operator= (one_bit b2){
            b=b2.b;
            return *this;
        }
    
        operator int()const{return int(b);}
        operator unsigned int()const{return (unsigned int)(b);}
        operator char()const{return char(b);}
        operator unsigned char()const{return (unsigned char)(b);}
        operator long()const{return long(b);}
        operator unsigned long()const{return (unsigned long)(b);}
        operator long long()const{return (long long)(b);}
        operator unsigned long long()const{return (unsigned long long)(b);}
    };
    
    one_bit bits[8];
    
    评论

报告相同问题?

问题事件

  • 创建了问题 5月6日

悬赏问题

  • ¥15 is not in the mmseg::model registry。报错,模型注册表找不到自定义模块。
  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音
  • ¥30 Pytorch深度学习服务器跑不通问题解决?
  • ¥15 部分客户订单定位有误的问题
  • ¥15 如何在maya程序中利用python编写领子和褶裥的模型的方法
  • ¥15 Bug traq 数据包 大概什么价
  • ¥15 在anaconda上pytorch和paddle paddle下载报错
  • ¥25 自动填写QQ腾讯文档收集表