[英]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.