簡體   English   中英

從裸數據到C ++包裝器的類型轉換

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM