c语言中强制类型转换存在问题:
任意类型之间都可以进行转换,编译器很难判断其正确性;
在源码中无法快速定位所有使用强制类型转换的语句
1.static_cast
用于基本类型之间的转换,但不能用于基本指针类型的转换。
用于有继承关系类对象之间的转换和指针之间的转化。
static_cast是在编译期间进行转换的,无法在运行时检测类型
static_cast.cpp
#include <iostream>
using namespace std;
class A
{};
class B : public A
{};
int main()
{
int a=1;
double b;
//a=(int)b; //c语言中的强制转换
a=static_cast<int>(b); //用于普通类型之间的转换
int *pa;
char *pc;
//pa=(int *)pc; //c语言中的强制转换
// pa=static_cast<int *>(pc); //不能用于基本数据类型指针之间的转换
A aa;
B bb;
aa=static_cast<A>(bb); //用于继承关系类之间的转换
//bb=static_cast<B>(aa); //错误,基类对象不可以给派生类
A *pA;
B *pB;
//用于有继承关系类指针之间的转换
pA=static_cast<A *>(&bb); //基类指针指向派生类对象
pB=static_cast<B *>(&aa); //派生类指针指向基类对象
return 0;
}
2.reinterpret_cast
用于指针类型间的强制转换;用于整数和指针类型间的强制转换。
reinterpret_cast直接从二进制位进行复制,是一种极其不安全的转换
reinterpret_cast.cpp
#include <iostream>
using namespace std;
int main()
{
int a=1;
char b;
int *pa=&a;
char *pb=&b;
pa=reinterpret_cast<int *>(pb); //用于基本指针类型之间的转换
pb=reinterpret_cast<char *>(0x100); //用于整数和指针之间的转换
return 0;
}
3.const_cast
用于去除变量的const属性
#include <iostream>
using namespace std;
int main()
{
const int a = 1;
int *pa = const_cast<int *>(&a); //去掉变量的const属性
const int &b = 1;
int &c = const_cast<int &>(b);
c = 2;
cout << b << endl; //b=2
const int d = 1; //常量
int &e = const_cast<int &>(d);
e = 3;
cout << d << endl; //d=1
return 0;
}
4.dynamic_cast
用于类层次之间的转换,还可用于类之间的交叉转换
有类检查的功能,比static_cast安全
#include <iostream>
using namespace std;
class A
{
private:
int m_a;
public:
virtual void show()
{}
};
class B : public A
{
private:
int m_b;
public:
virtual void show()
{}
};
int main()
{
A a;
B b;
A *pa=&a;
B *pb=&b;
pa=&b;
pa=dynamic_cast<A *>(&b);
pb=static_cast<B *>(&a);
//pb=dynamic_cast<B *>(&a); //必须具备多态的特性
return 0;
}
转载自Steve Sun的专栏
C++的类型转换控制符能告诉程序员或读者我们这个转换的目的是什么,我们只要看一下代码的类型转换控制符,就能明白我们想要达到什么样的目的.
1)static_cast <T*> (content) 静态转换.在编译期间处理
它主要用于C++中内置的基本数据类型之间的转换.但是没有运行时类型的检测来保证转换的安全性.
为什么需要static_cast类型的转换?
a.用于基类和子类之间的指针或引用的转换。这种转换把子类的指针或引用转换为基类表示是安全的;
进行下行转换,把基类的指针或引用转换为子类表示时,由于没有进行动态类型检测,所以是不安全的;
b.把void类型的指针转换成目标类型的指针(不安全).
c.用于内置的基本的数据类型之间的转换.
d.把任何类型的表达式转换成void类型的.
注意:static_cast不会转换掉content的const,volatile,__unaligned属性
2)const_cast<T*>(content):去常转换;编译时执行;
它主要作用同一个类型之间的去常和添加常属性之间的转换.不能用做不同的类型之间的转换.
它可以把一个不是常属性的转换成常属性的,同时它也可以对一个本是常属性的类型进行去常.
3)dynamic_cast<T*>(content) 动态类型转换;也是向下安全转型;是在运行的时候执行;
通常用于基类和派生类之间的转换.转换时会进行类型安全检查。
a.不能用于内置的基本数据类型之间的转换.
b.dynamic_cast转换成功的话返回的是类的指针或引用,失败返回null;
c.dynamic_cast进行的转换的时候基类中一定要有虚函数,因为只有类中有了虚函数,
才说明它希望让基类指针或引用指向其派生类对象的情况,这样才有意义.
这是由于运行时类型检查需要运行时类型的信息,而这些信息存储在虚函数表中.
d.在类的转换时,在类层次间进行转换的时候,dynamic_cast和static_cast进行上行转换
的时候效果是一样的;但是在进行下行转换的时候,dynamic_cast会进行类型检查所以
它更安全.它可以让指向基类的指针转换为指向其子类的指针或是其兄弟类的指针;
4)reinterpret_cast<T*>(content)重解释类型转换;
它有着和C风格强制类型转换同样的功能;它可以转化任何的内置数据类型为其他的类型,
同时它也可以把任何类型的指针转化为其他的类型;它的机理是对二进制数据进行重新的
的解释,不会改变原来的格式,而static_cast会改变原来的格式;