对C++中类型转换的一些探讨

来源:互联网 发布:淘宝哪家店买手办 编辑:程序博客网 时间:2024/06/05 08:03
        类型转换经常发生在变量赋值(或初始化)、函数参数传递、函数返回值等地方。首先要注意一点:不管是显示的类型转换还是隐式的类型转换,都有一个到转换结果类型的临时变量的产生
譬如:
       int i = 1.2;    //实际的赋值过程可能是 int temp = 1.2; int i = temp;
所以这就很能解释下面这个错误:
      double d = 2.1;
      int &ri = d;  //错误!因为这里ri的引用是对保存类型转换结果的那个临时变量的引用。
      int *pi = &d;   //错误,这里很明显视图将一块表示浮点数的内存区域用int来解释。
同样也能够解释函数参数传递中不允许传递到引用的类型转换和使用引用返回局部对象。因为保存函数返回值的匿名变量也是在函数调用栈区的,返回语句所做的就是去初始化该匿名变量,如果这个初始化的过程还有类型转换的话,那么同样有类型转换的临时变量的产生。(可以参看B.S《C++ 程序设计语言》P130~P133)

再来分析一下显示强制类型转换:
int _tmain(int argc, _TCHAR* argv[])
{
    float i = 5;
//1    static_cast<int>(i) = 4;   //错误!
//2  static_cast<int&>(i) =  4    //错误!
//3    static_cast<float>(i) =4;   //正确
//4    static_cast<float&>(i) = 4;   //正确
    cout<<i<<endl;;
    return 0;
}
注意强制类型转换运算符的返回值为存储转换结果的临时变量,4是正确的,应为该临时变量是对i的引用,所以输出4;3是正确的,同样结果输出4,可以认为是转换前后类型相同,所以实际上转换根本不发生,所以3实际上等于:i =4;2很明显是错误的把float转换到int&;1是错误的编译出错信息是“'=' : left operand must be l-value”,实际上可以理解为该转换结果的临时变量赋值是不安全且完全没有必要的。

最后在分析下显示强制类型转换和多态的组合:
在派生类的赋值运算符的实现中,会经常发现static_cast<base&>(*this) = rhs;此类的语句来调用该派生类基类成员的operator=,这里的从派生类对象derived到临时变量基类对象的引用base&是可行的(多态),然后再调用基类的operator=操作符。

再来讨论类型转换后存放变量的内存空间的变化:
大部分的类型转换后存放变量的内存空间肯定有了变化。但要注意无符号变量和有符号变量之间的转换是其对应的内存地址二进制表示不变
unsigned char 到char的转换内存二进制表示不变。所以可以互相转换。
#include "stdafx.h"
#include <iostream>
#include <fstream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    unsigned char uc = 129;
    ofstream ofs("out.txt", ios::binary);
    cout<<(int)uc<<endl;
    ofs.write((char*)&uc, sizeof(uc));
    char c = char(uc);
    cout<<(int)c<<endl;
    ofs.write(&c, sizeof(c));
    ofs.close();
    return 0;
}
打开out.txt,切换到二进制查看模式,都是0x81.
由于转换到int过程中对内存地址的解释的不同,
控制台输出:    129(unsigned char 内存0x81第一个bit解释为数字位)
                            -127(char 内存0x81第一个bit解释为符号位,0x81为-127的补码表示)

下面这段代码可能更加清楚一些,可以看出对同一块内存地址0x81,不同的类型解释,得到不同的结果。
int _tmain(int argc, _TCHAR* argv[])
{
    unsigned char uc = 129;
    unsigned char *puc = &uc;
    char *pc = (char*)puc;
    cout<<int(*puc)<<endl;
    cout<<int(*pc)<<endl;
    return 0;
}
输出:    129
            -127
原创粉丝点击