转型操作符
简述:主要讨论四个新的转型操作符:
1) static_cast
2) const_cast
3) dynamic_cast
4) reinterpret_cast
1. static_cast
测试代码:
/***************************static_cast****************************/
/*用来表示普通的类型转换*/
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
int firstNum = 1;
int secondNum = 5;
double result_1 = firstNum / secondNum;
cout << "result_1: " << result_1 << endl;
//C式旧型类型转换执行非多态的转换
double result_2 = ((double)firstNum) / secondNum;
cout << "result_2: " << result_2 << endl;
//static_cast用于代替C中通常的转换操作。做为隐式类型转换使用
double result_3 = static_cast<double>(firstNum) / secondNum;
cout << "result_3: " << result_3 << endl;
return 0;
}
测试输出:
2 const_cast
简述: 用于取消常量的常量性
1)未使用const_cast
/***************************const_cast****************************/
//1.未使用const_cast,没有取消const int num 的常量性
#include <iostream>
using namespace std;
void ChangeNum(int& x){
x = -1;
}
int main(int argc, char **argv)
{
const int num = 100;
ChangeNum(num);
return 0;
}
编译错误:const int地方不能用int
2) 使用旧式C常量类型转换
//2.旧式C的类型转换
#include <iostream>
using namespace std;
void ChangeNum(int& num){
num = -1;
}
/*用来表示普通的类型转换*/
int main(int argc, char **argv)
{
const int num = 100;
ChangeNum((int&)num);
cout << num;
return 0;
}
输出:
3)使用const_static
//3.使用const_cast,在函数中取消const int num 的常量性,但是函数外原常量值未作改变
#include <iostream>
using namespace std;
void ChangeNum(int& x){
x = -1;
}
int main(int argc, char **argv)
{
const int num = 100;
ChangeNum(const_cast<int&>(num));
//函数外num的值未作更改
cout << num;
return 0;
}
输出:虽然将常量传入了函数,但是出了函数,原先的const int num的值并没有变化
3.dynamic_cast
简述:
用来执行集成体系中“ 安全向下转型或跨系转型 ”
一定要涉及继承机制!
同时,dynamic_cast进行基类子类转换时,基类必须有虚函数!
1) 首先测试一下,不用向下转型可能发生的错误
///***************************dynamic_cast****************************/
#include <iostream>
using namespace std;
class A{
int A_num;
public:
virtual void f(){};
};
class Aa : public A{
int Aa_num;
public:
void f(){}
};
class Ab : public A{
int Ab_num;
void f(){}
};
void Func(Aa* Aa_object){
}
/*用来表示普通的类型转换*/
int main(int argc, char **argv)
{
A *A_object = new A();
Aa Aa_object;
Ab Ab_object;
Func(A_object);
// Func(dynamic_cast<Aa*>(A_object));
return 0;
}
编译错误:
2) 使用向下转型dynamic_cast,传入指针,
///***************************dynamic_cast****************************/
#include <iostream>
using namespace std;
class A{
int A_num;
public:
virtual void f(){};
};
class Aa : public A{
int Aa_num;
public:
void f(){}
};
class Ab : public A{
int Ab_num;
void f(){}
};
void Func(Aa* Aa_object){
}
/*用来表示普通的类型转换*/
int main(int argc, char **argv)
{
A *A_object = new A();
Aa Aa_object;
Ab Ab_object;
// Func(A_object);
Func(dynamic_cast<Aa*>(A_object));
return 0;
}
3) 使用向下转型dynamic_cast,传入引用:
传入的是A_object所指的Aa 如果A_object真的只想这个类;否则跑出一个exception
///***************************dynamic_cast****************************/
#include <iostream>
using namespace std;
class A{
int A_num;
public:
virtual void f(){};
};
class Aa : public A{
int Aa_num;
public:
void f(){}
};
class Ab : public A{
int Ab_num;
void f(){}
};
void Func(Aa& Aa_object){
}
/*用来表示普通的类型转换*/
int main(int argc, char **argv)
{
A *A_object = new A;
Aa Aa_object;
Ab Ab_object;
// Func(A_object);
//传入的是A_object所指的东西
Func(dynamic_cast<Aa&>(*A_object));
return 0;
}
抛出的异常:
以上dynamic_cast 类型转换时是必须注意到
a . 基类中一定要有虚函数否则
b . 指针之间转化
如果没有在基类中加入虚函数是会发生错误的
如下,
4) 未加虚函数virtual f(){} 代码:
///***************************dynamic_cast****************************/
#include <iostream>
using namespace std;
class A{
int A_num;
public:
// virtual void f(){};
};
class Aa : public A{
int Aa_num;
public:
// void f(){}
};
class Ab : public A{
int Ab_num;
// void f(){}
};
void Func(Aa* Aa_object){
}
/*用来表示普通的类型转换*/
int main(int argc, char **argv)
{
A *A_object = new A();
Aa Aa_object;
Ab Ab_object;
// Func(A_object);
Func(dynamic_cast<Aa*>(A_object));
return 0;
}
编译错误:
编译器会认为,上述类型转换不是发生在继承关系时的。
4.reinterpret_cast
简述:
该类型转换可以将 不同返回值类型的 函数指针 进行转换,但是传入的参数一定要相同
同时也认识了一下平时不常用的函数指针
测试代码:
///***************************reinterpret_cast****************************/
//该类型转换可以将 不同返回值类型的 函数指针 转换但是传入的参数一定要相同
#include <iostream>
#include <stdio.h>
using namespace std;
typedef void (*PrintFunc)(int );
void printA(int a)
{
printf("aa\n");
}
void printB(int b)
{
printf("bb\n");
}
int FuncInt(int m){
printf("int func\n");
return 0;
}
int main(int argc, char **argv)
{
PrintFunc func;
func = printA;
func(1);
func = printB;
func(1);
//int FuncInt转型为void ,但是函数传入的参数相同
func = reinterpret_cast<PrintFunc>(&FuncInt);
func(1);
return 0;
}
输出: