[英]Typecasting from bare data to C++ wrapper
假設我在程序中的某處分配了一些數據,例如:
some_type a;
我想將這些數據包裝在一個類中以便訪問。 是否有效說,
class Foo {
private:
some_type _val;
public:
inline void doSomething() { c_doSomething(&_val); }
}
Foo *x = reinterpret_cast<Foo *>(&a);
x->double();
該類沒有虛函數,只包含我想要包裝的單個數據項。 C ++標准是否指定此reinterpret_cast
是安全有效的? sizeof(Foo) == sizeof(some_type)
,沒有地址對齊問題,還是其他什么? (在我的例子中,我將確保some_type
是一個原始類型,如int
或POD結構,但我很好奇如果我們不強制執行該限制會發生什么 - 例如,派生類像UIWidget
一樣的UIMenuItem
,或者其他東西。)
謝謝!
說...有效嗎
不,這是無效的。 有僅是類型少數a
可以被視為; 完整列表可以在我給另一個問題的答案中找到。
C ++標准是否指定此
reinterpret_cast
是安全有效的?
C ++標准對reinterpret_cast
很少。 它的行為幾乎完全是實現定義的,因此使用它通常是不可移植的。
這樣做的正確方法是
有一個Foo
構造函數,它接受一個some_type
參數並復制它或存儲一個引用或指針,或者
將“包裝器”接口實現為一組非成員函數, some_type
函數通過引用將some_type
對象作為參數。
1998分之14882/ 9.2.17:
“指向PODstruct對象的指針,使用reinterpret_cast進行適當轉換,指向其初始成員(或者如果該成員是位域,則指向它所在的單位),反之亦然。[注意:因此可能存在未命名的填充在PODstruct對象中,但不是在它的開頭,以實現適當的對齊。]“
因此,如果你的包裝器本身就是一個嚴格的POD就行了。 但是,訪問說明符意味着它不是嚴格意義上的POD。 也就是說,我很想知道當前實現是否因訪問說明符而改變了對象布局。 我認為,出於所有實際目的,你很高興。
對於元素不是POD的情況,接着是容器不是POD,因此所有的賭注都是關閉的。
因為只要現有的a有效,你的Foo對象才有效:
struct Foo {
some_type &base;
Foo(some_type &base) : base (base) {}
void doSomething() { c_doSomething(&base); }
}
//...
Foo x = a;
x.doSomething();
您想查找管理POD(普通舊數據)類型的規則。 如果C ++類是POD類型,那么是的,您可以投射它。
實際發生的事情和如何處理別名的細節是實現定義的,但通常是合理的,應該與類似的C類型或結構相匹配。
我碰巧在我的一個項目中使用了很多東西,它在共享內存映射中實現了B +樹。 它已經在GCC中跨多種類型的Linux和BSD(包括Mac OS X)工作。它在帶有MSVC的Windows中也可以正常工作。
是的,只要您創建的包裝類型(在您的示例中為Foo
)是POD類型,這是有效的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.