C++ 创建两个具有重叠内存的变量

C++ Create two variables with overlapping memory

本文关键字:重叠 内存 变量 两个 创建 C++      更新时间:2023-10-16

我有两个structsRectPoint。遗憾的是,我无法改变它们的执行。

矩形的定义是:

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类与布局兼容,因为它们具有共同的初始前缀,并且它们是标准布局(或 C++03 中的普通旧数据(。

这意味着

Rect r = {1,2,3,4};
Point* p = &reinterpret_cast<Point*>(&r);

生成一个指向 Rect rxy字段p Point指针。 修改*pxy字段将修改r中的值,修改r.xr.y将修改*p中的值。 嗯,有点。

缺点是混叠和严格混叠的概念。 如果在编译器中关闭严格别名,它将丢失一些优化,但上述方法将起作用。

要使其在严格的混叠下工作,您需要将RectPoint存储在一个联合中:

union MyUnion {
  Rect r;
  Point p;
};
MyUnion u = Rect{1,2,3,4};

现在,p.xp.y在任何情况下都提到了r.xr.y,其中"允许检查 它们中的任何一个的共同初始部分在任何地方声明 工会的完整类型是可见的"。 因此,在可以看到MyUnion的地方,您是安全的 - 但是在看不到的地方,编译器可以自由地将指针到Point修改x视为无法修改指向Rect指针的x。 这对于优化目的很重要,因为没有它,重新排序不变的子表达式几乎是不可能的。

如果你想隐藏wh,也许你可以创建一个基于Rect值的"临时"Point并使用这种结构......然后,如果xy可以与原始值不同,则可以将当前值设置为原始值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类并同时隐藏wh......你做不到

根据评论和答案,这似乎是不可能的。哦,好吧,用指针会是一个很好的技巧!

我只会保留矩形,而不是隐藏wh成员。

感谢所有回答:)的人

乙尼法特尔

附言我使用的代码是用 C 语言编写的,我正在使用C++与之交互。对不起,忘了提:/

P.P.S.感谢您提供解释工会约阿希姆的链接,我从来没有了解过他们!