我有两个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
,它似乎没有用,并且重新分配了地址,这显然也没有用。
有人有什么想法吗?我知道这可能不是最好的做法,但这将是一个巧妙的技巧,使事情变得更加简单。
hnefatl
答案 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 ++具有布局兼容的概念。您的Point
和Rect
类是布局兼容的,因为它们有一个共同的初始前缀,它们是标准布局(或C ++ 03中的普通旧数据)。
这意味着
Rect r = {1,2,3,4};
Point* p = &reinterpret_cast<Point*>(&r);
生成Point
指针p
,指向Rect x
的{{1}}和y
字段。修改r
的{{1}}和x
字段将修改y
中的值,修改*p
和r
将修改r.x
中的值{1}}。嗯,有点。
缺点是别名和严格别名的概念。如果在编译器中关闭严格别名,它将失去一些优化,但上述方法将起作用。
要使其与严格别名工作一起使用,您需要将r.y
和*p
存储在一个联合中:
Rect
现在Point
和union MyUnion {
Rect r;
Point p;
};
MyUnion u = Rect{1,2,3,4};
在任何“允许检查”的情况下引用p.x
和p.y
其中任何一个的共同初始部分是声明的
联合的完整类型是可见的。所以在可以看到r.x
的地方,你是安全的 - 但是在无法看到它的地方,编译器可以自由地处理一个指针 - r.y
修改MyUnion
由于无法修改指向Point
的{{1}}指针。这对于优化目的很重要,因为如果没有重新排序,未更改的子表达式几乎不可能。
答案 2 :(得分:0)
如果您想隐藏w
和h
,也许您可以根据Point
值创建“临时”Rect
并使用此结构...然后,如果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
......你就不能这样做
答案 3 :(得分:0)
根据评论和答案,似乎这是不可能的。哦,好吧,指针会很棒!
我会保留矩形,而不是隐藏w
和h
成员。
感谢所有回答的人:)
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;