如何在 C++ 中初始化嵌套结构数组?

How to initialize nested array of structs in C++?

我有以下定义:

struct Display_font_char 
{
    unsigned char * data;
    int originX;
    int originY;
    unsigned int width;
    unsigned int height;
    unsigned int delta;
};

struct Display_font 
{
    Display_font_char * chars;
    unsigned char rangeStart;
    unsigned char rangeEnd;
};

如何就地初始化它?我正在尝试:

const Display_font font = 
{
    {
        {
            { 1, 2, 3 },
            1,
            2,
            3u,
            4u,
            5u
        }
    },
    1u,
    2u
}

但是,我收到错误消息:“无法使用 int 类型的值来初始化 Display_font_char 类型的字段 *”

您不能使用包含多个值的大括号初始化列表来初始化指针。

这是一个如何初始化 class:

实例的示例
unsigned char uc[] = { 1, 2, 3 };
Display_font_char fc {
    uc,
    1,
    2,
    3u,
    4u,
    5u,
};
const Display_font font = 
{
    &fc,
    1u,
    2u,
};

作为旁注,如果你要切换到 C,那么你可以使用复合文字:

const struct Display_font font = 
{
    &(struct Display_font_char){
        (unsigned char []){ 1, 2, 3 },
        1,
        2,
        3u,
        4u,
        5u
    },
    1u,
    2u
};

但是,C++ 中不存在复合文字。

为了初始化你的指针,你必须首先创建指针结构,例如使用new

请注意,如果您想将 Display_font.charsDisplay_font_char.data 视为数组,您应该保存它们的大小(例如通过 size_t data_size 成员)。

在下面的示例中,我使用 new[] 创建数组,稍后使用 delete[] 删除它们。

[Demo]

#include <iostream>  // cout
#include <ostream>

struct Display_font_char 
{
    unsigned char* data;
    size_t data_size;
    int originX;
    int originY;
    unsigned int width;
    unsigned int height;
    unsigned int delta;
};
std::ostream& operator<<(std::ostream& os, const Display_font_char& f)
{
    os << "\tdata = [";
    for (size_t i{0}; i < f.data_size; ++i)
    {
        os << ((i == 0) ? "" : ", ") << static_cast<int>(f.data[i]);
    }
    os << "]\n";
    os << "\toriginX = " << f.originX << "\n";
    os << "\toriginY = " << f.originY << "\n";
    os << "\twidth = " << f.width << "\n";
    os << "\theight = " << f.height << "\n";
    os << "\tdelta = " << f.delta << "\n";
    return os;
}

struct Display_font 
{
    Display_font_char* chars;
    size_t chars_size;
    unsigned char rangeStart;
    unsigned char rangeEnd;
};
std::ostream& operator<<(std::ostream& os, const Display_font& f)
{
    os << "chars = [\n";
    for (size_t i{0}; i < f.chars_size; ++i)
    {
        os << ((i == 0) ? "" : ", ") << f.chars[i];
    }
    os << "]\n";
    os << "rangeStart = " << static_cast<int>(f.rangeStart) << "\n";
    os << "rangeEnd = " << static_cast<int>(f.rangeEnd) << "\n";
    return os;
}

int main()
{
    const Display_font font = {
        new Display_font_char[1]{
            new unsigned char[4]{1, 2, 3},
            3,  // data size
            1, 2,
            3u, 4u, 5u
        },
        1,  // chars size
        1, 2
    };
    std::cout << font;
    delete[] font.chars[0].data;
    delete[] font.chars;
}

这个其他版本使用 std::vector 而不是 Display_font_char*unsigned char*,因此您不必关心内存 allocations/deallocations。

[Demo]

#include <iostream>  // cout
#include <ostream>
#include <vector>

struct Display_font_char
{
    std::vector<unsigned char> data;
    int originX;
    int originY;
    unsigned int width;
    unsigned int height;
    unsigned int delta;
};
std::ostream& operator<<(std::ostream& os, const Display_font_char& f)
{
    os << "\tdata = [";
    bool first{true};
    for (auto& d : f.data)
    {
        os << (first ? "" : ", ") << static_cast<int>(d);
        first = false;
    }
    os << "]\n";
    os << "\toriginX = " << f.originX << "\n";
    os << "\toriginY = " << f.originY << "\n";
    os << "\twidth = " << f.width << "\n";
    os << "\theight = " << f.height << "\n";
    os << "\tdelta = " << f.delta << "\n";
    return os;
}

struct Display_font 
{
    std::vector<Display_font_char> chars;
    unsigned char rangeStart;
    unsigned char rangeEnd;

};
std::ostream& operator<<(std::ostream& os, const Display_font& f)
{
    os << "chars = [\n";
    bool first{true};
    for (auto& c : f.chars)
    {
        os << (first ? "" : ", ") << c;
        first = false;
    }
    os << "]\n";
    os << "trangeStart = " << static_cast<int>(f.rangeStart) << "\n";
    os << "rangeEnd = " << static_cast<int>(f.rangeEnd) << "\n";
    return os;
}

int main()
{
    const Display_font font{
        { { {1, 2, 3}, 1, 2, 3u, 4u, 5u } },
        1,
        2
    };
    std::cout << font;
}