static_cast(静态类型转换)
- 子类转父类
- 父类转子类(不保证正确)
- 基本类型转换
- void*转其他类型
- 其他类型转void*
dynamic_cast(动态类型转换)
dynamic_cast会在运行时期检查类型转换是否合法,有一定安全性,但因为是运行时检查,所以会损失性能。
dynamic_cast只能转换引用或指针,在转换失败时会返回空指针,引用则抛出异常。
我的理解,在向下转换以及横向转换时,才需要dynamic_cast。在向下转换时可以检查基类的指针是否真的指向了子类对象,相较于static_cast多了一个类型检查。
class A {
private:
int a;
public:
A(int a_) :a(a_) {}
virtual void vprintfself(void) {
std::cout <<"a"<<this->a<<std::endl;
}
};
class B: public A {
private:
int b;
public:
B(int a_,int b_) :A(a_) { b = b_; }
void vprintfself(void) {
std::cout <<"b "<<this->b<< std::endl;
}
};
int main()
{
A* a = new A(2);
B* static_p_a_B = static_cast<B*>(a);
B* dymatic_p_a_B =dynamic_cast<B*>(a);//空指针
static_p_a_B->vprintfself();
dymatic_p_a_B->vprintfself();//报错
}
横向转换是指以下情况:
class Shape {
public: virtual ~Shape();
virtual void draw() const = 0;
};
class Rollable {
public: virtual ~Rollable();
virtual void roll() = 0;
};
class Circle : public Shape, public Rollable {
void draw() const;
void roll();
};
class Square : public Shape {
void draw() const;
};
//横向转型失败
Shape *pShape1 = new Square();
Rollable *pRollable1 = dynamic_cast<Rollable*>(pShape2);//pRollable为NULL
//横向转型成功
Shape *pShape2 = new Circle();
Rollable *pRollable2 = dynamic_cast<Rollable*>(pShape2);//pRollable不为NULL
这时static_cast做不到的。
const_cast
将常量变量转换为可赋值的变量,但注意,原来的常量名称的值不会被改变。因为在预编译阶段,将常量转换为真实数字,就如同宏定义的常量一样。
int main()
{
const int fuck = 1000;
int* a = const_cast<int*>(&fuck);
std::cout << "address of a is " << a<<std::endl;
std::cout << "address of fuck is " << &fuck << std::endl;
*a = 1100;
std::cout << "a is " << *a << std::endl;
std::cout << "fuck is " << fuck << std::endl;
}
输出:
address of a is 0097FA48
address of fuck is 0097FA48
a is 1100
fuck is 1000
reinterpret_cast
该转换是为数据的二进制形式重新解释,但是不改变其值。
但是!!!C语言的会将一些数值之类的截断等处理,比如浮点型转整形。浮点型跟整形的保存数据处理方式是不同的,但经过处理之后就变成了截断的数值。而此时如果用reinterpret_cast来转换,得到的数值肯定是让你诧异的值,因为其实直接将那二进制的值重新当做另外一种数据类型来解释的。
所以这个转换少使用较好。