文档声明:
以下资料均属于本人在学习过程中产出的学习笔记,如果错误或者遗漏之处,请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。
笔记资料仅供学习交流使用,转载请标明出处,谢谢配合。
如果存在相关知识点的遗漏,可以在评论区留言,看到后将在第一时间更新。
作者: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;
}