I have something of this nature:
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;
}
}
};
With the understanding of unions the for loop within the constructor will initialize m_256
to all 0s
and the other 2 arrays are just another version or alias of it, so those arrays should be initialized as well since the memory size is exactly the same and the memory is shared.
I'd prefer not to go through a for loop to initialize all values of the array to some default value. Also since there are 3 arrays within this union, you can only have 1 non static member with an initialize list within a union. So this is valid.
union {
int m_256[256]{};
int m_16[16][16];
int m_4[4][4][4][4];
}
Instead of using the for loop within the constructor or typing the same number manually 256 times, is there a short hand method that will initialize all values within the array to the same initial value?
EDIT
Based on a comment from user657267
he said:
Keep in mind that technically you can't write to one union member and read from another
Consider this: without making any changes to the class above and simply adding this operator overload:
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<<
Now in the main function we can do this.
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;
}
Other than the printed array table the last two values are:
39, 201
Now if we scroll through the table and look for (0,2,1,3) the value is 39 and to test out if 201 is correct; we used [12][9]. If you are using a double for loop to index a flat array the indexing is equal to (i * num_j + j ) so, knowing that the 2D Array Version of this 1D or 4D array is [16][16] in size we can calculate this value mathematically: 12 * 16 + 9 = 201.
Within my specific case doesn't this invalidate his statement? In c++ are unions not the sharing of memory between two variables, and if you have the same data type such as int & int doesn't this make them alias of one another? I was surely able to initialize the 1D flat array, use the 4D version to print a table, and was able to extract values from both the 2D & 4D versions.
Edit
I know what others are saying about you can't write to one and access another technically because of a case as such:
union foo {
int x;
char y;
};
Here is an excellent answer to a different question on unions Difference Between Structs & Unions. However, in my case here, the data type and the size in memory for all three arrays are the same. Also, if one value is changed in one I am expecting it to change in another. These are just different ways to access the same memory. Eventually this "nameless union" will be a private member within my class, and there will be public methods to retrieve a const reference to the full array, to retrieve the contents from the arrays by index values from each of the 3 types, and to place contents into the array by any of the three types.
All the boiler plate will be done behind the scenes in private. So I do not see this as in issue, and the behavior here is what I am after. It is not as if I'm creating an instance of a union where it is mixed types. I'm not doing bit fields with them. I'm basically conserving memory so I don't have to have 3 arrays that are 256 x (size of element) then have to have a bunch of copying from one array to another array semantics, this property of how unions work, is what I'm actually after. It is 1/3 the amount of memory used by a single instance of the class in use, probably 20% faster and more efficient without having to keep 3 different independent arrays synchronized every time an element is added or removed, or moved within the array.
As structs are defined: They will allocate enough memory for every data type and instance within the struct. You can set each data type independently
As unions are defined: They will allocate enough memory for the largest data type within the union. If you set one data type, it will change the other data type.
In the context of my class, the union is nameless so you can not create an instance of it, however you can access any of its members. In the case here with these three arrays:
byte a[256]; // 256 bytes
byte b[16][16]; // 16 x 16 = 256 bytes
byte c[4][4][4][4]; // 4^4 = 256 bytes
They are exactly the same size; and in my all three of these are the same array in my class. This is used to access the data in different ways.