I've a small problem:
class A {
public:
enum _type {TYPE1=0,TYPE2,TYPE3} type;
union U{
struct _type1 {
//somme data
} type1;
struct _type2 {
//some other data
std::vector<int> v;
} type2;
struct _type3 {
// some other data
} type3;
U() { //constuctor
switch(type){ // access to A::type => not accept at compile time
case TYPE1 : /*init type1*/ break;
case TYPE2 : /* init type2 */; new(&v) std::vector<int>; break;
case TYPE3 : /* init type3 */ break;
default : break;
}
~U(){ //I need it to delete placement new
switch(type)
{
//same probleme
case TYPE2: v.~vector<int>(); break;
default : break;
}
}
}
};
the error:
invalid use of non-static data member
As you can see, I just need to access in the union constructor to a data of the main class. I need this to deal with "unrestricted union" (data member of the union are object in reality) so I really need to use union and not a other class.
Edit: Finaly, I find a solution for this case:
class A {
public:
A(int t); // <= add U() code here
~A(); // <= add ~U() code here
union {
//same union data
}; //move to anonymous union
};
You have to pass an instance of A to the constructor, just like for anything else. The fact that the union is declared inside A is irrelevant.
Edit: You're just reinventing boost::variant
, by the way.
You don't physically have any "inner union" object inside your A
objects. All you did is declare a type inside another type. This affects naming and access rights, but creates no other relationships between A
and U
.
If you really want to physically have an object of type U
as a member of objects of type A
you have to declare a member of type U
in class A
. That will create a physical relationship between an A
object and its member of type U
. C++ language does not provide standard means for determining the address of the owner from its data member, but it can be achieved by some semi-legal hacks.
For example, if you declare
class A {
public:
union U {
...
};
...
U u;
};
you will be able to gain access to the entire A
from inside methods of U
by doing
A *pa = static_cast<A *>((void *) ((char *) this - offsetof(A, u)));
This is obviously a rather inelegant hack, relying among other things of the hardcoded name u
of the class member. But the technical possibility is there nevertheless.
Or you can simply pass a pointer/reference to the enveloping A
object to the U
object and perform access through that pointer/reference.
However, there's a problem of another nature specific to your example. You seem to be trying to access the owner class from constructor and destructor of a member subobject. Member subobjects are constructed before the owner object. And member subobjects are destructed after the owner object. This means that what you will see from U
s constructor and destructor is either not yet constructed or already destructed object of type A
. Trying to access the other members of the owner object (especially non-trivial ones) in this case is not a good idea.
Your constructor and destructor are at the wrong place. Move them from the union to the class A
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.