如何用C ++构造函数初始化位域?(How to initialize bitfields with a C++ Constructor?)

编程入门 行业动态 更新时间:2024-10-27 17:11:24
如何用C ++构造函数初始化位域?(How to initialize bitfields with a C++ Constructor?)

首先,我不关心可移植性,并且可以安全地假设字节序不会改变。 假设我读取了一个硬件寄存器值,我想将这个寄存器值覆盖在位域上,以便我可以在不使用位掩码的情况下引用寄存器中的各个字段。

编辑:修正GMan指出的问题,并调整代码,以便未来的读者更清楚。

请参阅: Anders K.&Michael J的答案,以获得更有说服力的解决方案。

#include <iostream> /// \class HardwareRegister /// Abstracts out bitfields in a hardware register. /// \warning This is non-portable code. class HardwareRegister { public: /// Constructor. /// \param[in] registerValue - the value of the entire register. The /// value will be overlayed onto the bitfields /// defined in this class. HardwareRegister(unsigned long registerValue = 0) { /// Lots of casting to get registerValue to overlay on top of the /// bitfields *this = *(reinterpret_cast<HardwareRegister*>(&registerValue)); } /// Bitfields of this register. /// The data type of this field should be the same size as the register /// unsigned short for 16 bit register /// unsigned long for 32 bit register. /// /// \warning Remember endianess! Order of the following bitfields are /// important. /// Big Endian - Start with the most signifcant bits first. /// Little Endian - Start with the least signifcant bits first. unsigned long field1: 8; unsigned long field2:16; unsigned long field3: 8; }; //end class Hardware int main() { unsigned long registerValue = 0xFFFFFF00; HardwareRegister testRegister(registerValue); // Prints out for little endianess machine // Field 1 = 0 // Field 2 = 65535 // Field 3 = 255 std::cout << "Field 1 = " << testRegister.field1 << std::endl; std::cout << "Field 2 = " << testRegister.field2 << std::endl; std::cout << "Field 3 = " << testRegister.field3 << std::endl; }

First off, I’m not concerned with portability, and can safely assume that the endianness will not change. Assuming I read a hardware register value, I would like to overlay that register value over bitfields so that I can refer to the individual fields in the register without using bit masks.

EDIT: Fixed problems pointed out by GMan, and adjusted the code so it's clearer for future readers.

SEE: Anders K. & Michael J's answers below for a more eloquent solution.

#include <iostream> /// \class HardwareRegister /// Abstracts out bitfields in a hardware register. /// \warning This is non-portable code. class HardwareRegister { public: /// Constructor. /// \param[in] registerValue - the value of the entire register. The /// value will be overlayed onto the bitfields /// defined in this class. HardwareRegister(unsigned long registerValue = 0) { /// Lots of casting to get registerValue to overlay on top of the /// bitfields *this = *(reinterpret_cast<HardwareRegister*>(&registerValue)); } /// Bitfields of this register. /// The data type of this field should be the same size as the register /// unsigned short for 16 bit register /// unsigned long for 32 bit register. /// /// \warning Remember endianess! Order of the following bitfields are /// important. /// Big Endian - Start with the most signifcant bits first. /// Little Endian - Start with the least signifcant bits first. unsigned long field1: 8; unsigned long field2:16; unsigned long field3: 8; }; //end class Hardware int main() { unsigned long registerValue = 0xFFFFFF00; HardwareRegister testRegister(registerValue); // Prints out for little endianess machine // Field 1 = 0 // Field 2 = 65535 // Field 3 = 255 std::cout << "Field 1 = " << testRegister.field1 << std::endl; std::cout << "Field 2 = " << testRegister.field2 << std::endl; std::cout << "Field 3 = " << testRegister.field3 << std::endl; }

最满意答案

不要这样做

*this = *(reinterpret_cast<HW_Register*>(&registerValue));

不应该用这种方式弄乱'this'指针:

HW_Register reg(val) HW_Register *reg = new HW_Register(val)

这里'这'是在记忆中的两个不同的地方

相反,有一个内部联合/结构来保存价值,这种方式很容易来回转换(因为你对可移植性不感兴趣)

例如

union { struct { unsigned short field1:2; unsigned short field2:4; unsigned short field3:2; ... } bits; unsigned short value; } reg

编辑:真正足够的名字'登记'

don't do this

*this = *(reinterpret_cast<HW_Register*>(&registerValue));

the 'this' pointer shouldn't be fiddled with in that way:

HW_Register reg(val) HW_Register *reg = new HW_Register(val)

here 'this' is in two different places in memory

instead have an internal union/struct to hold the value, that way its easy to convert back and forth (since you are not interested in portability)

e.g.

union { struct { unsigned short field1:2; unsigned short field2:4; unsigned short field3:2; ... } bits; unsigned short value; } reg

edit: true enough with the name 'register'

更多推荐

本文发布于:2023-07-05 06:50:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1034327.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:初始化   如何用   函数   Constructor   initialize

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!