2011-03-25 197 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