[英]C++ Create two variables with overlapping memory
我有两个structs
, Rect
和Point
。 遗憾的是,我无法更改其实现。
Rect的定义是:
typedef struct Rect
{
int x, y;
int w, h;
} Rect;
Point
的定义是:
typedef struct Point
{
int x, y;
} Point;
我想有效地保留一个Rect,但是将w
/ h
成员隐藏起来。
我想知道是否可以使用内存中的相同地址创建Point对象,以便每个对象之间共享x
/ y
内存?
我尝试使用placement new
,它似乎没有用,并且重新分配了地址,这显然也没有用。
有人有想法么? 我知道这可能不是最佳做法,但这将是一个巧妙的窍门,使事情处理起来更加简单。
赫内法特
您应该将Rect隐藏在自己的类中,并提供所需的接口。 就像是:
class MyRect
{
private:
Rect _rect;
public:
MyRect(const Rect& rect);
int& x() { return _rect.x; }
int& y() { return _rect.y; }
}
C ++具有布局兼容的概念。 您的Point
和Rect
类具有Rect
初始前缀,并且它们是标准布局(或C ++ 03中的普通旧数据),因此它们与布局兼容。
这意味着
Rect r = {1,2,3,4};
Point* p = &reinterpret_cast<Point*>(&r);
生成指向Pointt r
的x
和y
字段的Point
指针p
。 修改*p
的x
和y
字段将修改r
的值,而修改rx
和ry
则将修改*p
的值。 好吧,有点。
缺点是别名和严格别名的概念。 如果在编译器中关闭严格的别名,它将失去一些优化,但是上面的方法仍然有效。
为了使其能够与严格的别名一起使用,您需要将Rect
和Point
都存储在一个联合中:
union MyUnion {
Rect r;
Point p;
};
MyUnion u = Rect{1,2,3,4};
现在px
和py
在“允许在可以看到联合的完整类型的声明的任何地方检查其中任何一个的公共初始部分”的任何情况下都引用rx
和ry
。 因此,在可以看到MyUnion
地方,您是安全的-但是,在看不到MyUnion
地方,编译器可以自由地将修改x
的指针指向Point
视为无法修改指向Rect
的x
。 这对于优化目的很重要,因为如果不重新排序,不变的子表达式将几乎变得不可能。
如果您想隐藏w
和h
,也许您可以基于Rect
值创建一个“临时” Point
并使用此结构...那么,如果x
和y
可以与原始值不同,则可以将当前值设置为原始Rect
变量:
Rect original_rect;
// ...
Point point;
point.x = original_rect.x;
point.y = original_rect.y;
// code that use Point instead of Rect
// ...
// Set current values to original variable
original_rect.x = point.x;
original_rect.y = point.y;
另一方面,如果您需要使用Rect
类并同时隐藏w
和h
,则无法执行此操作
根据评论和答案,这似乎是不可能的。 哦,对了,指针指针将是一个很好的技巧!
我只保留矩形,不隐藏w
和h
成员。
感谢所有回答:)
赫内法特
PS我正在使用的代码是用C编写的,并且我正在使用C ++与之交互。 对不起,忘了提及:/
PPS感谢您为解释约阿希姆工会的链接提供帮助,我永远也无法了解他们!
一种选择是让Rect
从Point
派生,以便它继承其成员。
typedef struct Rect: struct Point
{
int w, h;
} Rect;
并在需要时使用所需类型的指针。
另一种选择是保留原始类型并使用狂野的演员表,例如
struct Point* MyPseudoPointPtr= (struct Point*)&MyRect;
这也适用于参考
struct Point& MyPseudoPoint= *(struct Point*)&MyRect;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.