【问题标题】:C++ reinterpret_cast object to string and backC++ reinterpret_cast 对象到字符串并返回
【发布时间】:2016-06-10 21:01:45
【问题描述】:

我刚刚在 C++ 中发现了 reinterpret_cast,我正在尝试了解更多有关它的信息。我写了这段代码:

struct Human{
    string name;
    char gender;
    int age;
    Human(string n, char g, int a) : name(n), gender(g), age(a) {}
};

int main()
{
    Human h("John", 'M', 26);
    char* s = reinterpret_cast<char*>(&h);
    Human *hh = reinterpret_cast<Human*>(s);
    cout << hh->name << " " << hh->gender << " " << hh->age << endl;
}

效果很好,完全符合预期。现在我想将char * 转换为std::string,然后从这个字符串中取回Human 对象:

int main()
{
    Human h("John", 'M', 26);
    char* s = reinterpret_cast<char*>(&h);

    string str = s;
    Human *hh = reinterpret_cast<Human*>(&str);

    cout << hh->name << " " << hh->gender << " " << hh->age << endl; // prints wrong values
}

有没有人想办法克服这个问题?

谢谢。

【问题讨论】:

  • 虽然有一些方法可以使这项工作发挥作用,但这闻起来很有趣。事实上,这闻起来像 meta.stackexchange.com/questions/66377/what-is-the-xy-problem 。那么,您认为使用这种方法需要解决的真正问题是什么?
  • 第一个例子严重违反了the strict aliasing rule
  • 好吧,正如链接文章中所解释的那样,“char *”可以免除别名。即使这实际上没问题,但仍然不推荐。
  • @A.Omar 啊,那么是的,您可以将指向对象的指针转换为另一个指针。但是,这很重要,尝试通过套接字发送任何复杂的东西在几乎所有情况下都不会按预期工作。以普通的std::string 为例。 std::string 对象实际上并不包含实际的字符串,它包含一个指向字符串的 pointer,发送 std::string 对象将发送指针而不是它指向的数据(字符串) .在另一个过程中,您收到的指针不会指向同一事物(如果在任何有效内存中)。
  • @A.Omar:虽然这在理论上可行,但有时这不是一个好主意。首先,您的结构不能包含单个指针(或对象中的指针),因为它没有意义。此外,诸如位数、类型大小、打包、编译器、编译器版本和字节序差异等许多因素都会改变结构在跨平台内存中的布局方式。如果您需要序列化一个对象 - 只需以已知格式逐字节写入即可。

标签: c++ string object casting reinterpret-cast


【解决方案1】:

在你做的第二个程序中

string str = s;

您创建了一个与指针s 完全无关的全新对象。从str 获取地址会给你一个指向str 的指针,而不是它包含的“字符串”。

另外,使用reinterpret_cast 是告诉编译器“我知道我在做什么”的一种方式,如果你实际上不知道发生了什么,那么你无疑会进入未定义行为的领域 当您尝试使用 s 指向的“字符串”初始化 str 时会发生这种情况,因为它不是真正的字符串。

【讨论】:

  • 更不用说因为s 甚至不是指向正确的C 字符串的指针,你最多只能在std::string 中得到一些毫无意义的东西,最坏的情况是你的程序会崩溃当它试图从未分配的内存中读取时。
  • 如何string str = s;可能创建一个与指针s 无关的对象,而s 对其构造至关重要?您的意思是与它的地址无关?
  • @GManNickG 我没有说一个新的指针,说的是一个新的object,并且尝试获取新对象的地址将导致指向该新对象的指针这与s 没有任何关系。
  • @GManNickG:即使构造函数接受s,它也不会以任何方式将s 的实际值存储在对象中。它所做的只是将指向它的(无意义的)数据复制到std::string 中。因此,我认为生成的 std::strings 没有持久的关系。
  • @GManNickG 但是指针 s 仅作为参数传递给构造函数(在这种情况下),这是字符串对象 str 和指针 s 之间最接近的关系。一旦构造函数返回,strs 有什么关系?他们不是。字符串对象str 有自己的指针,它指向的内存完全不同于s
猜你喜欢
  • 2014-09-02
  • 2014-07-30
  • 1970-01-01
  • 1970-01-01
  • 2014-08-27
  • 2015-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多