在类c++中的并集中初始化数组

Initializing an array within a union in a class c++

本文关键字:集中 初始化 数组 c++ 在类      更新时间:2023-10-16

我有这种性质的东西:

SomeClass {
public:
     union {
         int m_256[256];
         int m_16[16][16];
         int m_4[4][4][4][4];
     }
    SomeClass() {
        // Initialize Array to some default value
        for ( unsigned u = 0; u < 256; u++ ) {
            m_256[u] = 0;
        }
    }         
};

随着对并集的理解,构造函数中的for循环将把m_256初始化为所有0s,而其他2个数组只是它的另一个版本或别名,因此这些数组也应该初始化,因为内存大小完全相同,并且内存是共享的。

我不希望通过for循环将数组的所有值初始化为某个默认值。此外,由于该联合中有3个数组,因此在一个联合中只能有1个具有初始化列表的非静态成员。所以这是有效的。

union {
    int m_256[256]{};
    int m_16[16][16];
    int m_4[4][4][4][4];
}

有没有一种简单的方法可以将数组中的所有值初始化为相同的初始值,而不是在构造函数中使用for循环或手动输入相同的数字256次?

编辑

根据user657267的评论,他说:

请记住,从技术上讲,你不能给一个工会成员写信,也不能从另一个上阅读

考虑一下:不需要对上面的类进行任何更改,只需添加这个运算符重载:

std::ostream& operator<<( std::ostream& out, const SomeClass& s ) {    
    out << std::endl;
    out << "{Box, Slice, Row, Column}n";
    for (unsigned box = 0; box < 4; box++) {
        for (unsigned slice = 0; slice < 4; slice++) {
            for (unsigned row = 0; row < 4; row++) {
                for (unsigned col = 0; col < 4; col++) {
                    out << "(" << box << "," << slice << "," << row << "," << col << ") = "
                        << s.m_4[box][slice][row][col] << std::endl;
                }
            }
        }
    }
    return out;
} // operator<<

现在在主函数中,我们可以这样做。

int main() {
    SomeClass s;
    // Initialize This Array To Have Each Value Incremented From 0 - 255
    for ( unsigned u = 0; u < 256; u++ ) {
        s.m_256[u] = u;
    }
    // Print Out Our Array That Is In The Union Using The Overloaded Operator.
    // Note The Overloaded Operator Is Using The declaration of m_p4 and not m_p256
    std::cout << s << std::endl;
    // Now We Know That If You Extract A Value From Any Given Index It Will Return That Value. 
    // So Lets Pull Out Two Random Values From Using The Other Two Members of the Union.
    int A = s.m_4[0][2][1][3];
    int B = s.m_16[12][9];
    // Now Print Out A & B
    std::cout << A << ", " << B << std::endl;
    return 0;
}

除了打印的数组表之外,最后两个值是:

39, 201

现在,如果我们在表中滚动并查找(0,2,3),则值为39以测试201是否正确;我们使用了[12][9]。如果您使用double for循环来索引平面阵列,则索引等于(i*num_j+j),因此,知道此1D或4D阵列的2D阵列版本的大小为[16][16],我们可以从数学上计算该值:12*16+9=201。

在我的具体情况下,这难道不会使他的陈述无效吗?在c++中,并集不是两个变量之间的内存共享,如果你有相同的数据类型,比如int&int这不是让他们成为彼此的别名吗?我肯定能够初始化1D平面阵列,使用4D版本打印表格,并且能够从2D&4D版本。

编辑

我知道其他人在说什么,因为这样的情况,从技术上讲,你不能写信给一个,也不能访问另一个:

union foo {
    int x;
    char y;
};

这是对另一个关于并集的问题的一个很好的答案;工会。然而,在我的例子中,所有三个数组的数据类型和内存大小都是相同的。此外,如果一个值在一个值中发生变化,我预计它在另一个值中将发生变化。这些只是访问同一内存的不同方式。最终,这个"无名联合"将成为我的类中的私有成员,并且将有公共方法来检索对完整数组的const引用,通过3种类型中的每一种类型的索引值从数组中检索内容,以及通过这三种类型中任何一种类型将内容放入数组中。

所有的锅炉板都将在幕后私下完成。所以我不认为这是有问题的,这里的行为就是我想要的。这并不是说我在创建一个混合类型的并集实例。我不会和他们一起玩比特场。我基本上是在节省内存,所以我不必有3个256x(元素大小)的数组,然后必须从一个数组复制到另一个数组语义,这个联合如何工作的属性,就是我真正想要的。它是正在使用的类的单个实例所使用的内存量的1/3,可能快20%,效率更高,而不必每次在数组中添加、删除或移动元素时都保持3个不同的独立数组同步。

正如结构的定义:它们将为结构中的每个数据类型和实例分配足够的内存。您可以独立设置每种数据类型的

正如联合的定义:它们将为联合中最大的数据类型分配足够的内存。如果您设置了一种数据类型,它将更改另一种数据类别。

在我的类的上下文中,联合是匿名的,因此您不能创建它的实例,但是您可以访问它的任何成员。在这三个阵列的情况下:

 byte a[256];         // 256 bytes
 byte b[16][16];      // 16 x 16 = 256 bytes
 byte c[4][4][4][4];  // 4^4 = 256 bytes

它们的大小完全相同;在我的课堂上,这三个都是同一个数组。这用于以不同的方式访问数据。

循环肯定是一个过度杀伤:

std::fill(std::begin(m_256), std::end(m_256), 42); // fills with 42

除此之外,没有内置的语言构造;不过,这与上面的内容大致相同。