How to dynamically create a union instance in c++? - c++

I need to have several instances of a union as class variables, so how can I create a union instance in the heap? thank you

The same as creating any other object:
union MyUnion
{
unsigned char charValue[5];
unsigned int intValue;
};
MyUnion *myUnion = new MyUnion;
Your union is now on the heap. Note that a union is the size of it's largest data member.

My C++ is a bit rusty, but:
my_union_type *my_union = new my_union_type;
...
delete my_union;

Same as a struct :) You can use malloc() and do it the C way, or new for the C++ way. The secret is that structs, unions and classes are related; a struct is just a class (usually) without methods. There's more clarification in the following comments, should you care.

Use the new operator.

I'm not sure where you want to head with this. A union is a user-defined data or class type that, at any given time, contains only one object from its list of members. So starting from this, if you have a union defined like this:
union DataType
{
char ch;
integer i;
float f;
double d;
};
You can then use DataType as a type to define members in a class or as a type to define variables on the stack, just like regular types, struct or classes you define.

Use the new operator:
#include <iostream>
union u {
int a;
char b;
float c;
};
class c {
public:
c() { u1 = new u; u2 = new u; u3 = new u; }
~c() { delete u1; delete u2; delete u3; }
u *u1;
u *u2;
u *u3;
};
int main()
{
c *p = new c;
p->u1->a = 1;
p->u2->b = '0' + 2;
p->u3->c = 3.3;
std::cout << p->u1->a << '\n'
<< p->u2->b << '\n'
<< p->u3->c << std::endl;
delete c;
return 0;
}

Related

What happens if you put a struct within a struct?

struct b;
struct a {
int argx;
int argy;
b structB;
};
struct b {
int argw;
int argz;
a structA;
};
int main() {
a structA;
std::cout >> structA.argx >> std::endl;
// Couldn't you do std::cout >> structA.structB.structA.structB... ;
}
What will happen? Will there be recursive memory usage?
I was wondering this because I was doing something like this in my code.
That's not possible in C and C++. You can't use the struct b in the struct a before it is defined. Even if you use forward declarations you can only use a pointer or reference. You can't create an instance of an incomplete type.
You can't compile this code.
You can create a pointer to an incomplete type instead:
struct b;
struct a {
int argx = 1;
int argy;
b *structB;
};
struct b {
int argw = 2;
int argz;
a *structA;
};
int main() {
a structA;
b structB;
structA.structB = &structB;
structB.structA = &structA;
std::cout >> structA.argx >> '\n';
std::cout >> structA.structB->argw >> '\n';
std::cout >> structA.structB->structA->argx >> '\n';
}
Should be fine. I've used structs in other structs before and never noticed a difference. Then again I wasn't profiling performance.
I wouldn't have both structs include each other though. I feel like that would be bad.
Edit: As #Thomas Sablik pointed out you can't use struct b in a, because it wasn't defined before.
I was talking about using a in b not the other way around. (when I've used structs in structs before)

Assigning subobject

What is the proper way to assign a subobject? For example:
struct A {
int x = 2;
int y = 3;
};
struct B: A {
int z = 5;
};
int main() {
std::unique_ptr<B> bp{new B{}};
A a;
a.x = 12;
a.y = 13;
*(static_cast<A*>(bp.get())) = a; // happens to work, but is it the right way?
std::cout << bp->x << " " << bp->y << std::endl;
return 0;
}
This works (or happens to work?), but is awkward and relies on an assumption about the layout of B. So, what is the correct way?
This may be slightly more idiomatic:
bp->A::operator=(a);
This kind of thing is pretty rare though, so it is hard to say. In general, the more you can avoid casts the better, but having an explicit cast may be useful in this case to make it clear you are doing something unusual.
Typically, you don't assign subobjects. It's conceptually wrong and violates how inheritance is supposed to work. If you need this, perhaps you have the wrong abstraction and really want composition:
struct B {
A a;
};
std::unique_ptr<B> bp{new B{}};
A a{12, 13};
bp->a = a;

C++ same variable act as int and float

I have on situation, where i need to keep the value float as well as int. so tried like below. but no help. can any one help on this?
union Val {
int a;
float b;
};
Val p;
p.b = 45.56;
int k = p.a; // i want k should be 45;
I see that you say:
i dont want each time it to be converted from float to int [sic]
To do that you could use user-defined conversions to accomplish this.
So your struct would look like this:
class Val {
int a;
float b;
public:
Val& operator= (const int _a) {a = _a; b = _a + fmod(b, 1.0F); return *this;}
Val& operator= (const float _b) {b = _b; a = trunc(_b); return *this;}
operator int() {return a;}
operator float() {return b;}
};
Please note that what you really want to use is simply a float with static_cast<int> For astatic_cast:
No checks are performed during runtime to guarantee that the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe. On the other side, it does not incur the overhead of the type-safety checks of dynamic_cast.
I've provided an example of using Val here: http://ideone.com/XUesib but you could accomplish the exact same thing given float foo like this:
foo = 1.3F;
cout << static_cast<int>(foo) << endl << foo << endl;
foo = 13 + fmod(foo, 1.0F);
cout << static_cast<int>(foo) << endl << foo << endl;
I have on situation, where i need to keep the value float as well as int. so tried like below
You can't do it with a union. A union can only hold a single value inside at any time. You need two separate variables. You can keep them in side a struct if you like:
struct Val {
int a;
float b;
};
Now you can have both an int and a float.
Val p;
p.b = 45.56;
p.a = p.b;
int k = p.a; // no conversion
That said, since you apparently only use a to store a converted value of b, you should measure whether the conversions even affect performance.
You can use structure with constructor, and initialize your variables in it as you wish.
struct Val {
int a;
float b;
Val(float value) {
a = b = value;
}
};
So you can use it in loop and don't worry about conversations each time, just create your Val variable outside loop and use it.

c++ assigning dynamic struct

I really want to do the following:
(sorry about syntax, I have no idea how this is done)
struct Data {
int var = 5;
} data;
struct Data2 {
var;
} data2;
data2.var = data;
cout << data2.var.var; //prints 5
Basically I want to have a dynamic struct variable in a struct that can be given any struct as value and access it through the mains struct.
Please be nice. I really don't know how to explain it better and I really want to do this and been reading a lot yet haven't found any methods to do this.
Ps.
I DON'T want to do the following:
struct Data {
int var = 0;
} data;
struct Data2 {
data;
} data2;
I want it to be dynamic, that is, that I can change it any time during the program. Thank you.
Conceptually, you may (?) be asking about references:
#include <iostream>
int main() {
int x = 10;
int & xref = x;
std::cout << xref << "\n";
x = 20;
std::cout << xref << "\n";
}
That will print:
10
20
Underlying a reference is essentially a pointer, but it is one which can never be null...and notationally you don't have to "dereference" it. Were you using pointers, the above would look like:
#include <iostream>
int main() {
int x = 10;
int * xptr = &x;
std::cout << *xptr << "\n";
x = 20;
std::cout << *xptr << "\n";
}
Here they are applied to your example with minimal changes:
#include <iostream>
struct Data {
int var;
};
struct Data2 {
Data & var;
};
int main()
{
Data data = {5};
Data2 data2 {data};
std::cout << data2.var.var << "\n";
data.var = 10;
std::cout << data2.var.var << "\n";
return 0;
}
Odds are "this isn't what you actually want" (you shouldn't usually be exposing member variables, much less member variables that are references to other variables). And they shouldn't be all named var. Etc.
Still, references are an integral part of the language and worth learning about.
(Note: for brevity, you may omit the return 0;...only from main. That's assumed, and legal in the standard; and you may omit its arguments. But you must return an int.)
You can use void pointer like this:
#include <iostream>
using namespace std;
struct Data
{
int var;
}data;
struct Data2
{
void *var;
}data2;
int main()
{
data.var = 5;
data2.var = &data;
cout<<((Data *)data2.var)->var<<endl;
return 0;
}
But it is not safe because somtimes you can't make sure that other struct has member called var which may cause unexpected result.
Basically I want to have a dynamic struct variable in a struct that
can be given any struct as value and access it through the mains
struct.
You can emulate the effect of dynamic typing by using polymorphism. The following is a test example for your case.
#include <iostream>
using namespace std;
struct BaseDataStruct
{
virtual int get_data() = 0;
};
struct Data : BaseDataStruct
{
int var = 5;
virtual int get_data() { return var;}
} data;
struct Data2 {
BaseDataStruct* var;
} data2;
int main()
{
data2.var = &data;
cout<<data2.var->get_data();
return 0;
}
By using BaseDataStruct as an interface base class for all the structs which Data2::var is expected to point to you can achieve the "dynamic typing" behavior you are trying to get.
Note: I changed the Data2::var a to pointer to avoid object slicing. You will need to jump through many hoops to avoid that if you want to have it by value.
TL/DR: C++ is statically typed, so what you want to do is against the spirit of thr language. However, if you really have to you can use void* in C and boost::any in C++
Now a bit more about void* (to know more about boost::any refer to its documentation).
void* is a pointer that holds a raw address in memory. This value beyond this address could be everything: float, int or your struct. Here is the usage example.
struct Data {
int var = 5;
};
struct Data2 {
void* var;
};
int main() {
Data data;
Data2 data2;
data2.var = (void*)(&data);
cout << ((struct Data*)data2.var)->var << endl;
}
If the concept of pointers is new for you you can read about it here. Void pointers are explained there as well.

C++ Pointer to struct member

If I were to make a struct, say:
struct FOO{
int x, y, z, a, b, c;
}
int main(){
FOO foo = {1, 2, 3, 4, 5, 6};
return 0;
}
Would there be anyway to create a pointer that can access FOO's integer members?
Maybe by making pointer that points to foo and then somehow modifying it to increment in integers?
I know that if I were to make FOO a class instead with a method that returns a pointer to the first int, then I could cycle though the members with ++ or [i](in a for loop). But I want to know if I can access structure members simply by knowing the address of the struct (assuming I have a good understanding of how to navigate said struct)
Any insight would be much appreciated.
Thanks!
You can overload operator[] for the struct:
struct bar // ALL_UPPERCASE is for macros!
{
int a, b, c, d, e, f;
int operator[](size_t i) const
{
switch(i)
{
case 0: return a;
case 1: return b;
case 2: return c;
case 3: return d;
case 4: return e;
case 5: return f;
default: assert(false);
}
}
};
Just a thought and this might not work, but you could try doing a pointer to the foo struct and then shifting the pointer by the size of an int for each element. So something like:
int * ptr= & foo;
ptr++;
If I'm remembering my hardware design class well enough a struct is actually really similar to an array in memory it can just have variable sized blocks of memory for each of its indices.
struct FOO{
int x, y, z, a, b, c;
} __attribute__ ((packed))
FOO foo;
int *i = &foo;
In this case, the attribute ((packed)) eliminates the problem created by padding, since it get's rid of it. Afterwards incrementing i, grantees that it will be in the next element of the struct.
It's pretty straightforward:
Foo foo = { 1, 2, 3, 4, 5, 6 };
int* pfoo = &foo.x;
int structMembers = sizeof(Foo) / sizeof(int);
for (int i = 0; i < structMembers; i++)
{
cout << pfoo[i] << endl;
}
There's no difference between a struct and class aside from default access modifier (private in structs, public in classes). Thus whatever you can do with classes, you can do with structs.
As I understood you need this: https://en.cppreference.com/w/cpp/utility/functional/mem_fn
if you need own implementation take this:
#include <iostream>
struct Foo
{
int a = 1;
char b = 'a';
};
template<typename Struct, typename var_type>
const var_type member_get( Struct& obj, var_type Struct::* mem_var ) { return
obj.*mem_var; }
int main()
{
Foo x;
std::cout << member_get( x, &Foo::a ) << std::endl;
std::cout << member_get( x, &Foo::b ) << std::endl;
return 0;
}