在没有指针的情况下转换对象值

时间:2017-06-17 12:45:22

标签: c++ casting

假设AB是两个没有继承关系的类(或结构)(因此,object slicing不能工作)。我还有b类型的对象B。我想将其二进制值解释为A类型的值:

A a = b;

我可以使用reinterpret_cast,但我需要使用指针:

A a = reinterpret_cast<A>(b);       // error: invalid cast
A a = *reinterpret_cast<A *>(&b);   // correct [EDIT: see *footnote]

是否有更紧凑的方式(没有指针)做同样的事情? (包括sizeof(A) != sizeof(B)

的情况

使用指针工作的代码示例:[编辑:参见*脚注]

#include <iostream>
using namespace std;

struct C {
    int i;
    string s;
};

struct S {
    unsigned char data[sizeof(C)];
};

int main() {
    C c;
    c.i = 4;
    c.s = "this is a string";

    S s = *reinterpret_cast<S *>(&c);
    C s1 = *reinterpret_cast<C *>(&s);

    cout << s1.i << " " << s1.s << endl;
    cout << reinterpret_cast<C *>(&s)->i << endl;

    return 0;
}

*脚注:当我尝试它时它起作用了,但它实际上是一个未定义的行为(这意味着它可能起作用或不起作用) - 请参阅下面的评论

2 个答案:

答案 0 :(得分:1)

没有。我认为C ++语法中没有任何内容允许您隐式忽略类型。首先,这违背了静态类型的概念。其次,C ++在二进制级别缺乏标准化。因此,无论您采取什么措施来欺骗编译器您正在使用的类型,都可能特定于编译器实现。

话虽如此,如果你真的想这样做,你应该检查编译器的数据对齐/填充是如何工作的(即:struct padding in c++)以及是否有办法控制它(即:What is the meaning of "__attribute__((packed, aligned(4))) " )。如果您计划在编译器之间执行此操作(即:通过网络传输数据),那么您应该格外小心。还存在平台问题,例如不同的寻址模型和字节序。

答案 1 :(得分:-1)

是的,你可以在没有指针的情况下做到这一点:

A a = reinterpret_cast<A &>(b);       // note the '&'

注意,这可能是未定义的行为。查看http://en.cppreference.com/w/cpp/language/reinterpret_cast

的具体条件