静态类型转换(编译时类型检查)
关键字:static_cast
父类和子类之间转换
向上转换:子类向父类转换是安全的。
向下转型:父类转换成子类是不安全的
#include <iostream>
using namespace std;
class Base
{
};
class Child : public Base
{
};
//使用语法: static_cast<目标类型>(原始对象)
int main()
{
//向下转换,不安全
Base *base = NULL;
Child *child = static_cast<Child *>(base); //把base指针转换为child指针类型
//向上转换,安全
Child *child2 = NULL;
Base *base2 = static_cast<Base *>(child2);
}
基本数据类型转换
比如int转换char,double 等类型。这种安全性需要开发人员来保证。
#include <iostream>
using namespace std;
int main()
{
char a = 'a';
double d = static_cast<double> (a);
//double d = (double) a; //也可以通过编译,但是c风格的强转不检查合法性。
cout << d << endl;
}
强制类型转换是C风格的他不会检查合法性double a = (double)b ,所以尽量使用C++的静态转换
在前面文章介绍多态中也使用了向上转型和向下转型,使用的也是C风格的语法。这里学完static_cast关键字后使用这个。
动态类型转换(动态类型检查)
#include <iostream>
using namespace std;
class Base
{
public:
virtual void func(){};
};
class Child : public Base
{
public:
virtual void func() { cout << "child" << endl; };
};
class Other
{
};
//使用语法: dynamic_cast<目标类型>(原始对象)
int main()
{
char c = 'a';
//double d = dynamic_cast<double>(c); //失败,动态转换很严格,不支持基础类型转换
//向上转型, 安全
Child *child = NULL;
Base *base = dynamic_cast<Base *>(child);
//向下转型, 不安全
Base *base2 = NULL;
//Child *child2 = dynamic_cast<Child *>(base2); //失败
//发生多态情况,向上转型和向下转型都是安全的,因为创建空间时就是按照子类大小来创建的
//多态,父类引用或指针指向子类对象
Base *base3 = new Child;
Child *child3 = dynamic_cast<Child *>(base3); //把父类指针动态转换为子类
child3->func();
}
动态类型转换和静态类型转换的区别
C++中static_cast和dynamic_cast强制类型转换
#include <iostream>
using namespace std;
class Base
{
public:
virtual void func() { cout << "base" << endl; }
};
class Child : public Base
{
public:
virtual void func() { cout << "child" << endl; }
void func2() { cout << "this is func2" << endl; }
};
class Other
{
};
int main()
{
//多态,静态类型转换
Base *base1 = new Child;
Child *child1 = static_cast<Child *>(base1);
child1->func();//child
child1->func2();//this is func2
//多态,动态类型转换
Base *base2 = new Child;
Child *child2 = static_cast<Child *>(base2);
child2->func();//child
child2->func2();//this is func2
//单如果base指向单不是子类对象
//静态转换可能会报错,因为子类包含父类中没有的函数成员
Base *base3 = new Base;
Child *child3 = static_cast<Child *>(base3);
child3->func();//base
child3->func2();//this is func2
//动态转换,更加严格,返回空指针
Base *base4 = new Base;
Child *child4 = dynamic_cast<Child *>(base4);//返回空指针
child4->func();//Segmentation fault: 11
child4->func2();
}
总结
简言之C++转换可以分为向上转换和向下转型。
向上转型:static_cast和dynamic_cast效果一样,都安全;
向下转型:注意要转换的父类类型指针是否真的指向子类对象,如果是,static_cast和dynamic_cast都能成功;如果不是static_cast能返回,但是不安全,可能会出现访问越界错误,而dynamic_cast在运行时类型检查过程中,判定该过程不能转换,返回NULL。所以多态中使用dynamic_cast来进行向下转型,然后判断是否为NULL如果NULL则表示不能转换,进行错误处理。
使用指导
C语言强制转换语法尽量不要在c++中使用
使用c++中类型转换两个关键字。
static_cast : 在基本类型转换的时候使用,程序员自己保证转换安全
dynamic_cast:在类之间多态转换使用,向上转型和向下转型。