C ++使用重叠内存创建两个变量

时间:2014-08-05 10:35:07

标签: c++ pointers struct

我有两个structsRectPoint。遗憾的是,我无法改变他们的实施。

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,它似乎没有用,并且重新分配了地址,这显然也没有用。

有人有什么想法吗?我知道这可能不是最好的做法,但这将是一个巧妙的技巧,使事情变得更加简单。

hnefatl

5 个答案:

答案 0 :(得分:2)

你应该在你自己的类中隐藏你的Rect,提供你需要的接口。类似的东西:

class MyRect
{
    private:
        Rect _rect;

    public:
        MyRect(const Rect& rect);

        int& x() { return _rect.x; }
        int& y() { return _rect.y; }
}

答案 1 :(得分:1)

C ++具有布局兼容的概念。您的PointRect类是布局兼容的,因为它们有一个共同的初始前缀,它们是标准布局(或C ++ 03中的普通旧数据)。

这意味着

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

生成Point指针p,指向Rect x的{​​{1}}和y字段。修改r的{​​{1}}和x字段将修改y中的值,修改*pr将修改r.x中的值{1}}。嗯,有点。

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

要使其与严格别名工作一起使用,您需要将r.y*p存储在一个联合中:

Rect

现在Pointunion MyUnion { Rect r; Point p; }; MyUnion u = Rect{1,2,3,4}; 在任何“允许检查”的情况下引用p.xp.y     其中任何一个的共同初始部分是声明的     联合的完整类型是可见的。所以在可以看到r.x的地方,你是安全的 - 但是在无法看到它的地方,编译器可以自由地处理一个指针 - r.y修改MyUnion由于无法修改指向Point的{​​{1}}指针。这对于优化目的很重要,因为如果没有重新排序,未更改的子表达式几乎不可能。

答案 2 :(得分:0)

如果您想隐藏wh,也许您可​​以根据Point值创建“临时”Rect并使用此结构...然后,如果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 ......你就不能这样做

答案 3 :(得分:0)

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

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

感谢所有回答的人:)

hnefatl

P.S。我正在使用的代码是用C语言编写的,我正在使用C ++与它进行交互。对不起,忘了提一下:/

P.P.S。感谢您解释工会Joachim的链接,我永远无法了解他们!

答案 4 :(得分:-1)

一个选项是让Rect派生自Point,以便继承其成员。

typedef struct Rect: struct Point
{
    int w, h;
} Rect;

并在需要时使用您喜欢的类型的指针。

另一种选择是保留原始类型并使用狂野转换,例如

struct Point* MyPseudoPointPtr= (struct Point*)&MyRect;

这也适用于参考文献

struct Point& MyPseudoPoint= *(struct Point*)&MyRect;