是否可以用数组初始化结构体引用?

问题描述 投票:0回答:1

可以做这样的事情吗?:

struct S {
  int length;
  char data[100];
};

class C {
  uint8_t buffer[10];
  S& s = buffer[0];
};

如果我使用指针它可以编译,但使用引用会更方便:

class C {
  uint8_t buffer[10];
  S* s = (S*)buffer;
};

如果你想知道为什么要这样做,我有一个类似于上面的 S 的结构,用于发送和解析各种数据包。一些实际的数据包已知有限的长度,因此通过将成员声明为简单的 S 来分配超出所需空间的空间是没有意义的。

更新:

看来我没有把我的意图解释得不够清楚。也许一段实际代码可能会有所帮助。

typedef struct BP_Error_t {
    uint8_t cause;
    uint8_t error;
} BP_Error_t;

typedef struct BP_Upload_Rq_t {
    char    file[FILE_NAME_LENGTH];
    uint8_t size;
    uint8_t chunk[MAX_FILE_CHUNK];
} BP_Upload_Rq_t;

typedef struct BusPacket_t {
    uint8_t source;
    uint8_t target;
    uint8_t packet_id;
    uint8_t length;
    union {
        BP_Error_t          error;
        BP_TPI_Poll_t       tpi_poll;
        BP_TPI_ACK_t        tpi_ack;
        BP_WiFi_Poll_t      wifi_poll;
        BP_WiFi_ACK_t       wifi_ack;
        BP_Erase_Rq_t       erase_rq;
        BP_Erase_Rsp_t      erase_rsp;
        BP_Upload_Rq_t      upload_rq;
        BP_Upload_Rsp_t     upload_rsp;
        BP_Download_Rq_t    download_rq;
        BP_Download_Rsp_t   download_rsp;
        BP_DFU_Rq_t         dfu_rq;
        BP_DFU_Rsp_t        dfu_rsp;
    };
} BusPacket_t;

如您所见,我有一个代表各种数据包的结构。它的sizeof()将由最长的联合成员定义,即240字节。现在,假设我想作为类成员准备好发送错误数据包(只有 6 个字节长)。

如果我将其声明为BusPacket_t,我将白白浪费大量内存。所以我认为我可以分配一个 6 字节数组,然后将其别名为结构以便于访问。

c++ reference
1个回答
0
投票

请注意,如果您只是编写 C++,那么

typedef
是没有用的。

否则,我会扭转局面并首先声明

BusPacket_t
,然后将其用作其他结构中的“标头”,如下所示:

struct BusPacket_t {
    uint8_t source;
    uint8_t target;
    uint8_t packet_id;
    uint8_t length;
};

struct BP_Error_t {
    BusPacket_t packet;
    uint8_t     cause;
    uint8_t     error;
};

struct BP_Upload_Rq_t {
    BusPacket_t packet;
    char        file[FILE_NAME_LENGTH];
    uint8_t     size;
    uint8_t     chunk[MAX_FILE_CHUNK];
};

...

那么每个结构体的大小就是该结构体所需的大小,而不是最大可能的结构体。

我想您需要读取数据并将其写入网络流等位置,因此我会避免使用可能最终向结构中添加不需要的内容的类。否则,我将从

BusPacket_t
类派生并从其函数中受益(可能还有一些虚拟函数来获取该数据包的总大小)。

class BusPacket_t {
public:
    virtual size_t size() const = 0;
};

class BP_Error_t : public BusPacket_t {
public:
    virtual size_t size() const { return sizeof(BP_Error_t); }
};

但我认为 sizeof 不会返回虚拟表的大小(例如)。所以可能不是你想要的...

© www.soinside.com 2019 - 2024. All rights reserved.