在类c ++

时间:2016-04-06 08:15:11

标签: c++ arrays initialization unions

我有这种性质:

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,1,3),则值为39和 测试201是否正确;我们用[12] [9]。如果你使用双for循环来索引一个平面数组索引等于(i * num_j + j)那么,知道这个1D或4D数组的2D数组版本的大小是[16] [16]我们可以以数学方式计算该值:12 * 16 + 9 = 201。

在我的具体案例中,这不会使他的陈述无效吗?在c ++中,联合不是两个变量之间的内存共享,如果你有相同的数据类型,如int&amp; int这不会使它们成为彼此的别名吗?我当然能够初始化1D平面阵列,使用4D版本打印表格,并且能够从2D和2D中提取值。 4D版本。

修改

我知道别人在说什么,你不能写一个并且在技术上访问另一个因为这样的情况:

union foo {
    int x;
    char y;
};

对于关于工会Difference Between Structs & Unions的另一个问题,这是一个很好的答案。但是,在我的例子中,所有三个数组的数据类型和内存大小都是相同的。此外,如果一个值在一个值中更改,我希望它在另一个值中更改。这些只是访问相同内存的不同方法。最终这个“无名联盟”将成为我的类中的私有成员,并且将有公共方法来检索对完整数组的const引用,以通过来自3种类型中的每种类型的索引值从数组中检索内容,并且通过三种类型中的任何一种将内容放入数组中。

所有锅炉板都将在幕后私下完成。所以我不认为这是问题,这里的行为就是我所追求的。这并不是说我正在创建一个联合实例,它是混合类型。我不是跟他们做点话。我基本上保存内存,所以我不必拥有3个256 x(元素大小)的数组,然后必须从一个数组复制到另一个数组语义,这个联合工作方式的属性是什么我其实是在追求。它是正在使用的类的单个实例使用的内存量的1/3,每次添加或删除元素或在数组中移动时,不必保持3个不同的独立数组同步,速度提高20%,效率提高20% 。

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

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

在我的课程环境中,联盟是无名的,所以你不能创建它的实例,但是你可以访问它的任何成员。在这种情况下,使用这三个数组:

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

它们的大小完全相同;在我的这三个中,我班上的阵列是相同的。这用于以不同方式访问数据。

1 个答案:

答案 0 :(得分:2)

循环肯定是一种过度杀伤力:

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

除此之外,没有内置的语言结构;然而,它与上述几乎相同。