先看代码:
#include <iostream>
using namespace std;
class A
{
public:
A() {
cout << "A" << endl;
}
virtual ~A() {
cout << "~A" << endl;
}
virtual void print() {
cout << "A::Print()" << endl;
}
};
class B : public A
{
public:
B(int i) : index(i) {
cout << "B" << endl;
}
virtual ~B() {
cout << "~B" << endl;
}
virtual void print() {
cout << "B::Print(),index=" << index << endl;
}
int index;
};
int main(int argc, char *argv[])
{
A* pA = new A();
B* pB = new B(1);
A* pAB = new B(5);
B* pBA = static_cast<B*>(pA);
B* pBB = static_cast<B*>(pB);
B* pBAB = static_cast<B*>(pAB);
if (pBA) {
pBA->print();
}
if (pBB) {
pBB->print();
}
if (pBAB) {
pBAB->print();
}
delete pA;
delete pB;
return 0;
}
执行结果:
A
A
B
A
B
A::Print()
B::Print(),index=1
B::Print(),index=5
~A
~B
~A
pBB和pBAB没有任何问题,其本身就是B对象。pBA是从基类转换为B对象,但是调用的却是A::Print(),因为pA对象并没有构建B对象的内存,构建的仅是基类的内存,因此输出基类的print()。
现在改动代码,将A中的print函数去掉:
class A
{
public:
A() {
cout << "A" << endl;
}
virtual ~A() {
cout << "~A" << endl;
}
/*
virtual void print() {
cout << "A::Print()" << endl;
}
*/
};
程序在A::print()处崩溃!因为基类已经没有print()函数了。这里的pBA类型转换是由基类构造的对象变为派生类的指针,隐藏一个严重的程序BUG,但是编译器并没有在这里给与任何提示,还转换成功,得到了相应的B对象指针。
接下来使用dynamic_cast进行类型转换:
B* pBA = dynamic_cast<B*>(pA);
B* pBB = dynamic_cast<B*>(pB);
B* pBAB = dynamic_cast<B*>(pAB);
程序调试结果,pBA转换后为0,并没有转换成功,就可以在这里对转换对象进行判断。
因此在使用基本类型进行转换时,用static_cast,在涉及到对象之间的转换时用dynamic_cast。
float val = 10.00f;
int iVal = static_cast<int>(val);
A* pA = new B();
B* pB = dynamic_cast<B*>(pA);
if (pB != nullptr) {
pB->dosomething();
}