一:C语言常见的强制类型的转换有两种
隐式类型的转换和强制转换
所谓的隐式类型的强转就是相近的类型的转化,强制转换就是讲类型
如下:
int main()
{
int i = 1;
double j = i;
printf("%d,%2f\n", i, j); //隐式
int *p = &i;
int address = (int)p://强转
printf("%x,%d\n",p,address);
system("pause");
return 0;
}
二:c++强制类型的转换
static_cast/reinterpret_cast/cost_cast/dynamic_cast;
第一种:static_cast,用于静态转换,就是类型相关的转换,(隐式 );int转flaot,double转int等等。
void Tes1()
{
int i = 2;
double j = static_cast<double>(i);
printf("%d,%2f\n", i,j);
}
第二种:reinterpret_cast用于将一种类型转换成为另外一种类型。
void Test2()
{
int i = 10;
int *j = &i;
int address = reinterpret_cast<int>(j);
printf("%d,%d", i, j);
}
虽然可以编译通过,但是会出现不可确定的结果,所以最好少用。
第三种:cosnt_cast去常性
void Test3()
{
const int a = 2;
int *p = const_cast<int *>(&a);
*p = 3;
printf("%d", a);
}
按照说const修饰a,a不可被改变,但是加了const_cast去掉常性可以被改变,为什么结果不是3而是2呢?
我们在加上volatile再来观察下:
void Test3()
{
volatile const int a = 2;
int *p = const_cast<int *>(&a);
*p = 3;
printf("%d", a);
}
结果是3我们知道加上volatile表示在内存中取a的地址,现在想const修饰常量,内容一般存放在寄存器中,每次调用首先会在寄存器中找,这样会很快,可以理解为编译器的一种优化,加上volatile表明是在直接在内存中取而不是寄存器这样就可以明白3的由来。
第四种:dynamic_cast
用于将一个父类对象的指针转换成为一个子类对象的指针或者引用。
1.向上转型:子类对象的指针->指向父类对象的指针或者引用。
2.向下转型:父类对象的指针->指向子类对象的指针和引用。
class A
{
public:
virtual void fun1()
{
cout << "fun1()" << endl;
}
};
class B : public A
{
void fun2()
{
cout << "fun2()" << endl;
}
};
void fun(A*p)
{
B *p1 = static_cast<B*>(p);
B *p2 = dynamic_cast<B*>(p);
cout <<"p1:"<< p1 << endl;
cout << "p2:"<<p2 << endl;
}
int main()
{
A a;
B b;
fun(&a);
fun(&b);
system("pause");
return 0;
}
dynamic_cast会检查是否转换成功,若成功则转换,不成功返回0;
我们可以分两次更具体理解:
三:总结:
我们发现C++前三周类型的强转和C语言的原理相同,隐式(相近类型),不相关类型,const去常性,
第四个强转是C++独有的dynamic_cast用于将一个父类对象的指针转换为子类对象的指针或引用。
前提是只能用于虚函数的类。