#include <string>
#include <iostream>
using namespace std;
class Animal
{
public:
virtual void print1()
{
cout << "Animal1" << endl;
}
virtual void print()
{
cout << "Animal" << endl;
}
int aaa1;
int aaa2;
};
class Model
{
public:
virtual void printM1()
{
cout << "Model1" << endl;
}
virtual void printM()
{
cout << "Model" << endl;
}
int bbb1;
};
class Normal1
{
void printN()
{
cout << "Normal" << endl;
}
};
class Normal2
{
public:
void printN()
{
cout << "Normal" << endl;
}
};
class Cat: public Model,public Animal,public Normal1,public Normal2
{
public:
virtual void printM1()
{
cout << "CatModel1" << endl;
}
virtual void printM()
{
cout << "CatModel" << endl;
}
virtual void print1()
{
cout << "Cat1" << endl;
}
virtual void print()
{
cout << "Cat" << endl;
}
};
void test(Animal* _pA)
{
_pA->print();
}
void test1(Model* _pA)
{
_pA->printM1();
}
int _tmain(int argc, _TCHAR* argv[])
{
Animal* _pA = new Cat;
Model* _pA1 = (Model*)_pA; // ERROR
Model* _pA2 = dynamic_cast< Cat* >(_pA);
Model* _pA3 = (Cat*)_pA;
test(_pA);
test1(_pA1); // ERROR
test1(_pA2);
system("pause");
return 0;
}
为何test(_pA)和test1(_pA2)能正确打印,test1(_pA1)却出错了,调用了print1函数?
通过_pA,_pA1等等指针的数值. 也可以看出编译器帮我们做的转换的细节.
除了dynamic_cast是在运行时调用RTTI的机制向基类回溯查找,如果不能Cast就抛异常.其他的强转,
其他都是编译器在编译期就进行指针数值的判定. 一般来说, 虚表指针__vfptr就在this的位置.
如果继承自多个虚基类,就会有多个虚表指针.分别是在代表被继承的类内存块的开始.
在强转的时候,编译器会根据前后的代码块来判定是否可以通过子类指针转到基类,
返回基类在子类中内存块的开始(虚表指针__vfptr地址), 如果不行,就只是指针数值的复制.
比如 Model* _pA1 = (Model*)_pA; 这句.转换的时候,就只是指针数值复制,导致_pA1调用printM就错了.其实调用了print1函数.
虽然字面上是Model*类型指针,实际还是Animal*的指针.