none
struct的强制转换行为. RRS feed

  • 问题

  • C是不能对struct进行强制类型转换的. 刚才在VC++上做了实验, 发现一个奇怪的问题. 请看以下代码:

    #include <iostream>

    using namespace std;
    typedef struct
    {
    int si;
    } test_struct;


    int main()
    {
    test_struct ts1={0};
    test_struct& ts2 = (test_struct)ts1;

    cout << &ts1 <<endl;
    cout << &ts2 <<endl;

    return 0;
    }

    在上面的代码中, 对结构体进行强制转换, 会产生一个副本. 这样ts1跟ts2将指向两个不同的地址.

    这个结果是很让我吃惊的, 因为在印象中, 强制类型转换是不会改变地址, 也不会生成副本的.

    我没有找到这种情况比较官方的说法(翻了一下primer也没找到), 不知道有没有高手指点一下出处在哪里..

    PS:为了验证, 我在GCC上也做了测试, 发现同样的代码在GCC里面是编译不通过的. 说(test_struct)ts1不能赋值给引用

    请各位高手帮忙解解疑惑, 非常感谢.
    2009年9月19日 20:29

答案

  • 因为你转换写成了test_struct& ts2 = (test_struct)ts1;
    写成test_struct& ts2 = (test_struct&)ts1;
    就是你要的了。
    第一个表达式和第二个表达式有本质区别
    第一个是想转换为一个左值。显然是可以重新分配地址。所以需要一个新的对象
    而第二个表达式要转换为一个右值。不需要额外的地址空间。


    麻烦把正确答案设为解答。
    2009年9月20日 9:04
    版主

全部回复

  • 结构是可以强制转换的,只不过方法比较特殊.

    比如BLENDFUNCTION这个结构

    LONG x = 0x0000FF01;
    BLENDFUNCTION bft;
    bft = *((BLENDFUNCTION *)&x);

    这样,x就被强制转换成了BLENDFUNCTION结构.

    这种转换并不安全,你必须要完全的清楚结构含义才可以使用.
    0xBAADF00D
    2009年9月20日 3:04
    版主
  • Hey Vonger,

    谢谢你的回答. 但你说的是指针的转换, 而不是上文提到的结构类型的转换.

    通过转换指针是能够达到转换结构的目的, 但是我现在不清楚的是为什么VC++会支持(test_struct)ts1这种转换.
    而且这种转换为什么需要创建临时变量?
    这种行为在C++标准里面有没有提到, 或者这是一种未定义的行为.
    2009年9月20日 4:36
  • 因为你转换写成了test_struct& ts2 = (test_struct)ts1;
    写成test_struct& ts2 = (test_struct&)ts1;
    就是你要的了。
    第一个表达式和第二个表达式有本质区别
    第一个是想转换为一个左值。显然是可以重新分配地址。所以需要一个新的对象
    而第二个表达式要转换为一个右值。不需要额外的地址空间。


    麻烦把正确答案设为解答。
    2009年9月20日 9:04
    版主
  • 谢谢SplendourG老师的解答, 虽然还不是很明白, 但有了关键字可以搜一些资料了.

    看来我对C++的认识还差老远了. 努力学习去.

    如果老师有空再指点一两篇文章看看就最好了 ^_^
    2009年9月20日 12:53
  • 哇塞 学习学习


    擅长领域 Windows Desktop Experience Media Center Virtual Machine Windows System & Performance
    2009年9月20日 13:01
  • 谁说不会的,你对指针强制转换的话,指针也产生了一个副本。这根你指向的对象毫无关系。因此你对一个struct进行强制转换,struct产生了一个副本我觉得也是很正常的。
    2009年9月23日 1:37