[英]casting structure pointer to union pointer in C++
我有一个包含各种struct成员的Union。
union U {
struct S1 as_s1;
struct S2 as_s2;
…
};
如何在C ++中将struct as_s1的指针转换为Union U的指针?
我知道是不是因为这个 ,它可以用C铸造轻松完成。 但是我想使用C ++的Advance类类型转换的功能而不会引起任何错误。
来自标准6.9.2.4。
如果满足以下条件,则两个对象a和b是指针可互换的 :
- 它们是同一对象,或者
- 一个是标准布局联合对象,另一个是该对象的非静态数据成员(12.3),
- 一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则是该对象的第一个基类子对象(12.2),或者
- 存在一个对象c,使得a和c是指针可互换的,而c和b是指针可互换的。
如果两个对象是指针可互换的,则它们具有相同的地址,并且可以通过reinterpret_cast(8.2.10)从指向另一个的指针获得指向一个的指针。
这意味着您可以使用reinterpret_cast
将它们彼此转换。 但是,您不能访问错误类型的内存。 例如,以下是定义良好的代码:
#include <iostream>
struct S1 {
int i;
};
struct S2 {
short int i;
};
union U {
struct S1 as_s1;
struct S2 as_s2;
};
void printUnion(U* u, int type) {
if (type == 0){
S1 *s1 = reinterpret_cast<S1*>(u);
std::cout << s1->i << std::endl;
} else {
S2 *s2 = reinterpret_cast<S2*>(u);
std::cout << s2->i << std::endl;
}
}
int main() {
S1 s1{1};
printData(reinterpret_cast<U*>(&s1), 0);
S2 s2{2};
printData(reinterpret_cast<U*>(&s2), 1);
}
但是,如果您给printData
一个错误的类型参数,则该行为是不确定的。
在c ++中,很难想象一个需要良好设计的程序将需要强制转换。 在c中,如果您已经需要并集对象,则可能会用它来实现多态(当然那里没有reinterpret_cast)。 虽然通常是用void*
完成的。
此类指针转换的正确转换为reinterpret_cast:
#include <stdio.h>
struct S1 {
int x,y;
};
struct S2 {
double a,b;
};
union U {
struct S1 as_s1;
struct S2 as_s2;
};
int main() {
struct S1 mys1;
union U *uptr = reinterpret_cast<union U*>(&mys1);
uptr->as_s1.x = 42;
printf("%d\n",mys1.x);
return 0;
}
请注意,在本示例中,由于sizeof(struct S1) < sizeof(struct S2)
,并且您仅分配了S1
大小的足够内存,因此,如果尝试在uptr->as_s1.b
上执行任何操作,则会破坏堆栈。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.