C/C++ 编程 —— 隐式转换 和 显示转换学习笔记

文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。


笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
作者:Aliven888

1、隐式转换

  说白了就是在转换时不给系统提示具体的显示模型,让其自动转换,但是要记住一条编译器一般只支持 自下而上 的类型转换,例如 int 转 float 。

1.1、在混合类型的算术表达式中

// 低类型向高类型数值转化
int iA = 3;
double dB = 3.14;
double dC = iA + dB;  //iA 会被自动提升为 3.0

1.2、初始化指针

char chPtr = NULL;  // NULL(0) 被转化为了 int * 类型的空指针

1.3、参数传递

double fun(double db)  //在此处 1 会被转化为 1.0 
{
	return  db + 3.0;
}

double fun(int iA) 
{
	return iA + 2.0;  //在此处 1 会被转化为 1.0 
}

fun(1) 

1.3、条件表达式转 bool

int iA = 1;
if(iA) { ... }  // 0 - false, 非0 - true  

1.4、类对象之间的转化

void dosomething(A aObject);  
class A 
{  
	public:  
	A(int x = 0);  
}  
dosomething(20); // Ok 隐式转换,此时 x == 20

2、显示转换

  简单来说就是 强制转换,是一种 自上而下 的转换,但是可能会导致数据精度的丢失。

C++的四种强制转型形式:

  • const_cast(expression):静态转换
  • dynamic_cast(expression): 常量转换
  • reinterpret_cast(expression):
  • static_cast(expression):

2.1、static_cast – 静态转换

  static_cast 包含的转换类型有典型的非强制变换、窄化(有信息丢失)变换、使用 void* 的强制转换、隐式类型变换、类层次的静态定位。static_cast 是编译器允许的。

2.1.1、典型的非强制变换:

  从窄类型向宽类型的转换,如 char 向 short int , int , long int , float , double , long , double 的转换。

char a = 1;
long b = static_cast<long>(a);
2.1.2、窄化变换:

  与第1种相反,从宽类型向窄类型的变换,不安全转化,数据会丢失。

long b = 1;
char a = static_cast<char>(b);
2.1.3、使用void*的强制变换:
struct callback_param
{
    void *vp;
};
 
int a = 1;
struct callback_param cp;   
cp.vp = &a;      //编译器允许从任意类型指针向void*转换
 
int *ip = static_cast<int *>(cp.vp);
2.1.4、隐式类型转换:

包括(1)(2)

2.1.5、类层次的静态定位

  进行向上类型转换(派生类向基类转换)时,编译器清楚派生自什么祖先类,除了多继承(多继承转换后可能不为原地址,指针会在类层次中调整)。

2.2、常量转换(const_cast)

  从 const 转换为非 const,从 volatile 转换为非 volatile 。取得 const 对象的地址,会生成一个指向 const 的指针,volatile 同。

const int i = 0;
int *ip = const_cast<int *>(&i);
 
volatile int a = 0;
int *ap = const_cast<int *>(&a);

2.3、重解释转换(reinterpret_cast)

  最不安全的一种转换机制,将对象转变为完全不同类型的对象,这是低级的位操作。此方式通常不推荐。

struct msg_hdr
{
    int msg_type;
    int msg_len;
    char msg_data[0];
};
 
struct msg_data
{
    int data1;
    int data2;
};
 
struct msg_hdr *p = reinterpret_cast<struct msg_hdr *>(recvbuf);
struct msg_data *pdata = reinterpret_cast<struct msg_data *>(p->msg_data);

2.4、动态转换(dynamic_cast)

  类层次的向下转换(基类向派生类转换),转换过程中会通过RTTI检查转换类型是否正常,不正常将返回空。

#include <iostream>
using namespace std;

class pet
{
    public:
    virtual ~pet()
    {
    }
};

class dog : public pet
{
};

class cat : public pet
{
};

int main(void)
{
    pet *b = new cat;
    dog *d1 = dynamic_cast<dog *>(b);
    cat *d2 = dynamic_cast<cat *>(b);
    cout << "d1 = " << (long)d1 << endl;  // d1 = 0
    cout << "d2 = " << (long)d2 << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值