【问题标题】:Can anybody explain to the meaning of this expression?任何人都可以解释这个表达式的含义吗?
【发布时间】:2011-02-19 05:11:07
【问题描述】:
 void* GetData()
 {
    return reinterpret_cast<unsigned char*>(this);
 }

在这种情况下是否会发生自动类型强制?如何将我的类的对象转换为 unsigned char* ??

【问题讨论】:

  • 这个表达式在 g++ 上编译,并以某种方式返回一个值!这段代码实际上在我的代码库中工作:)
  • 谁能告诉我演员阵容比简单的return this 有什么优势?任何指针都可以隐式转换为void*(实际上该函数使用它来转换unsigned char*),因此this 也可以转换。第一次投射到unsigned char* 有什么意义?
  • @sbi 我认为 OP 打算检查成员的类对象的字节布局,所以返回类型应该是 unsigned char*。否则,在作为void* 接口时返回unsigned char* 毫无意义。
  • @WilhelmTell:但是当指针被投射到void* 时,这种对齐方式就丢失了。此外,任何检查都需要再次铸造void*。我可能仍然遗漏了一些东西,但您的回答似乎无法解释演员阵容。
  • @sbi: void * 保证与unsigned char * 具有相同的对齐方式;除此之外,我同意:void * 的演员阵容没有意义。

标签: c++ types type-conversion


【解决方案1】:

我假设你指的是return reinterpret_cast&lt;unsigned char*&gt;(this);

这是一个令人讨厌的块,它可能在解决错误的问题时采用了错误的方法。从技术上讲,它要求编译器将this 指针的类型重新解释为unsigned char* 指针。这里没有做任何工作:该语句仅指示编译器将指针视为不同的类型。如果这样解释类型是错误的,那将是灾难性的。

如果你想按位检查你的对象,那么你可以尝试这样的事情:

union inspect_klass {
    klass obj;
    char bits[sizeof(klass)];
};

编辑:我对上述工会的信心现在动摇了。暂时不要使用它,我正在寻找确认这个技巧确实被打破了。 :s

【讨论】:

  • 通过联合检查类是未定义的行为,但是:stackoverflow.com/questions/2310483/…
  • 天哪。从标准的草案,第 9.5 节第 1 段:... “联合的大小足以包含其最大的数据成员。” 任何人都可以确认我是正确的:这个意味着在上面的联合代码中,联合的大小可能大于其任何一个(大小等效)成员的大小。不仅如此,这两个成员的对齐方式也可能彼此不同。
  • @Wilhelm Alignment 不谈,标准规定,一旦您通过其中一个成员访问联合,通过另一个成员访问它是未定义的行为。当然,这个技巧被广泛使用,但这就是标准所说的。
  • @Neil 你能告诉我标准的确切位置吗?
  • 很好奇...联合类型中允许的内容在 C++0x 中发生了巨大变化。例如,所有对 POD 类型的引用都已删除 - 您现在可以将非 POD 类型存储在联合中。 9.5.1 中有这样说:“在一个联合中,在任何时候最多可以有一个非静态数据成员处于活动状态,即最多可以将一个非静态数据成员的值存储在任何时候的工会。”奇怪的是整个联合规范没有提到访问或其他类型,只有存储。
【解决方案2】:

我同意其他帖子:这几乎肯定不是你打算做的。

然而,IIRC,C++ 标准保证您能够将任何类型的指针(不包括函数或成员指针)转换为 unsigned char *void * 和返回而不进入未定义行为的领域。此外,您可以通过 char *unsigned char * 类型的左值访问任何对象(参见 ISO 14882:2003 第 3.10.15 节)。我以前使用过它来检查任意对象类型的内部表示。如果我对标准的理解是正确的,这会导致“实现定义的行为”(显然,类型的内部表示取决于实现)。

例如,

template<class T> std::vector<unsigned char> to_bytes (const T& t)
{
    const unsigned char *p = reinterpret_cast<const unsigned char *>(&t);
    return std::vector<unsigned char>(p, p + sizeof(T));
}

是一个模板函数,它将产生一个std::vector&lt;unsigned_char&gt;,它是对象内部表示的副本。

但是,当你返回时,你投到 void * 的事实让我怀疑你在做一些可能更令人讨厌和更不确定的事情。

【讨论】:

  • 如果您通过引用获取迭代器或向量,而不是返回向量,则可以使此函数更高效。尽管如此,我还是忍不住想知道是否有一种安全、正确的方法可以在编译时完成这项工作,而无需动态分配。
【解决方案3】:

首先,您的 GetData() 返回类型与表达式的返回类型不匹配。

reinterpret_cast 类似于老式的老式 C 转换 - 您只是返回一个指向 unsigned char* 的指针。这是完全不安全的。实际上,您正在为类的数据创建一个视图,可以按字节访问。

【讨论】:

    【解决方案4】:

    严格来说,unsigned char* 是一个字节数组。如果调用者要序列化数据,这似乎是一件非常合乎逻辑的事情。

    【讨论】:

    • 有一些方法可以序列化对象。这不是一个好方法。这很危险:客户端在重建对象时更好地知道要读取多少字节。 C++ 为您提供了更高级别的方法来做到这一点,因此您不太容易出错。然后当然还有boost序列化库之类的库。
    • 根本没有提到函数的范围。如果它不是私人的,我同意你的看法。并不意味着写它的人不打算序列化它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 2011-03-31
    • 2016-06-16
    相关资源
    最近更新 更多