2011-03-25 65 views
1


是否有可能在C++來字符數組轉換爲對象,像這樣:C++將char *轉換爲對象?

char* bytes = some bytes... 
MyObject obj = (MyObject)(bytes); 


如何定義演員?
謝謝:)

回答

9

你可能想定義MyObject來構造:

class MyObject { 
public: 
    explicit MyObject(const char* bytes); 
    ... 
}; 

MyObject::MyObject(const char* bytes) { 
    // do whatever you want to initialize "MyObject" from the byte string 
} 

,然後你可以使用它:

char* bytes = some bytes... 
MyObject obj = MyObject(bytes); // this will work 
MyObject obj(bytes);    // so will this 
+0

+1給出我懶得輸入的示例;) – AJG85 2011-03-25 17:48:32

+1

您也可以執行'MyObject obj = bytes;'。我建議在構造函數中使用'explicit'關鍵字來防止它,它可以避免一些令人驚訝的錯誤。 – 2011-03-25 17:50:14

+0

如果你這樣做,不要忘記三條規則(http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29)。您應該在其中添加析構函數並複製賦值運算符。 – 2011-03-25 17:55:45

3

如果字節字符串實際上代表MyObject類型的有效對象,就可以得到MyObject*

reinterpret_cast<MyObject *>(bytes) 

(這是不太可能的工作,雖然,除非char*是結果鑄造一個指向正確構造MyObject

+1

+1,但括號中的部分足夠重要,應刪除括號。 – 2011-03-25 17:44:19

+0

這不是UB嗎?它不違反嚴格的別名規則嗎? – ThomasMcLeod 2014-10-26 22:37:21

+0

@ThomasMcLeod'char *'不受該規則限制,所以只有當另一個非''*',非''MyObject *'指針/引用也引用'bytes'時。 – 2014-10-27 09:56:55

4

我可以在這裏看到兩種可能性。如果你有,你知道表示目標類型的數據,你可以使用一個reinterpret_cast,讓他們作爲該類型的物體進行處理:

MyObject *obj = reinterpret_cast<MyObject *>(bytes); 

如果你想在的創建指定類型的對象指定內存,可以使用placement new運營商在指定的地址構造一個對象:

char *bytes = whatever; 

MyObject *obj = new(bytes) MyObject; 

當你使用完對象,你不delete,你直接調用析構函數:

obj->~MyObject(); 

請注意,爲了達到此目的,您需要確保(如果沒有其他人)bytes指向針對目標類型正確對齊的數據。

+0

是的。這將在該位置構建一個新對象。如果你有一個已經構建好的對象(可能指針已經從MyObject *中輸出,你現在只是將它放回去)?那麼larsmans的答案就是要走的路。 – 2011-03-25 17:46:07

+0

@ T.E.D:不,不是。正如我編輯的答案中所指出的那樣,如果你知道真正代表的是指定類型的對象,你想使用'reinterpret_cast',而不是'static_cast'。 – 2011-03-25 17:48:02

+0

@Jerry:我剛剛在自己的答案中發現了錯誤,並且糾正了錯誤。 – 2011-03-25 17:49:37

-1

我喜歡Jerry Coffin和larsman的答案,具體取決於所討論的位置是否已經存在構造對象。

雖然還有一個皺紋。如果MyObject的類型碰巧符合POD class的條件,那麼只需對larsman建議的指針使用reintreprent轉換就可以了,因爲對象沒有真正需要的構造函數。

我說「可能」,因爲您的平臺在遠程可能會使用char *和類指針的不同表示。儘管我用過的大部分都沒有這樣做。

+0

這不應該是對這些答案之一的評論嗎?無論如何,地址類型並不重要:演員會根據需要進行轉換。問題在於標準是否允許將任意字節(地址轉換)重新解釋爲某種對象類型「T」,可能比編譯器無法驗證的「char」更嚴格。我確信它不會允許這個 - 除非所討論的char *'最初來自一個有效的分配'T *' - 而其他任何東西都是正式的UB。看到這個評論:http://stackoverflow.com/questions/5436092/c-casting-char-to-object#comment65366526_5436137 – 2016-08-17 23:02:13

+0

(複製評論的後代)即使_trivially copyable_ types - POD的超集符合每標準可以複製到'char'&back數組並且保持相同的值 - 實際上不會發出任何構造函數代碼,但Standard仍然要求這些對象具有定義良好的生命週期。這大概意味着編譯器必須看到代碼說'在這段內存中創建一個'struct T'',否則所有的投注都關閉並且意味着它可以發出不安全的代碼或優化嘗試。大多數編譯器允許任意投射,正如你在這裏非常模糊地推薦的那樣,並不能使其成爲UB。 – 2016-08-17 23:15:51

+0

它必須是對他們三個人的評論(這個軟件實際上是不允許的),再加上我有一些額外的材料直接解決了這個問題。我承認,當前的標準比我在編寫這篇文章時使用的C++ 11之前的標準要好得多。 – 2016-08-18 19:54:18