对象多态
向上转型
human peter{};
peter.age = 18; peter.gold = 200;
animal am = peter;
这里假设human类继承了animal类,human中原有属性gold,animal原有属性age,这里就是向上转型,子类对象可以转换成父类对象,但这样会发生内存切片
为什么能转换呢?因为动物类am里面的成员少于人类Peter里面的成员,转换时只需要丢掉多余的部分就行了,而如果am想要转成Peter,它里面还有部分类型都没有,转不了
内存切片:在这里就是转成animal类时会丢掉gold属性,因为animal里面只有age属性,不需要gold这个属性
向下转型
peter.age = 10; peter.gold = 200;
animal* am = &peter; /向上转型
human* ptr = (human*)am; /向下转型
ptr->bite();
ptr->eat();
std::cout << ptr->gold << std::endl;
animal里面有方法bite,human里面有方法eat
向下转型前必须先向上转型
类型转换
上面的向下转型那一句也可以写成这样
human* ptr= static_cast <human*> am
wolfman peter{};
void *ptr = &peter;
wolf *pwolf = &peter;
man *pman = &peter;
这里ptr和pwolf和pman有的值不一样,因为它们的类型不一样,如果写成下面这样呢
wolfman peter{};
void *ptr = &peter;
wolf *pwolf = (wolf*)ptr;
man *pman = (man*)ptr;
这里三个值一样吗?结果是一样 的,因为当把ptr是一个void类型,void就是无类型,也就是说它就是一个单纯的数值,所以即使类型为woolf*和man*,类型不一样,值也一样。
wolfman peter{};
void *ptr = &peter;
wolf *pwolf = (wolf*)&peter;
man *pman = (man*)&peter;
这里的值一样吗?结果是不一样,因为&peter最开始的类型为wolfman*,当把它转成wolf*时,意外i着它的类型和地址都发生了变化
特别注意*:当wolfman中如果继承了同一个类多次的时候,也就是多重继承的问题,不允许它进行类型转换,比如wolf继承了creature,man继承了creature,而wolfman继承了man和wol,这样导致wolfman中有多个creature,这时候不允许wolfman指针进行向上的类型转换,因为这个时候,不知道该指向哪个creature,但是如果wolfman是直接继承了creature,同时它也继承了wolf和man中的creature,这时候可以进行转换。
dinamic_cast
dinamic_cast<类型>()动态转换,只支持方法多态的类,即有虚函数的类,如果转换成功,返回指针,如果失败,返回空指针
跨类转换crosscast
指的是有共同子类,但是不同的两个父类之间的转换,它们可以通过dynamic转换,但是如果没有共同子类,无法通过dynamic进行转换
方法多态
静态多态
即函数重载和函数模板,animal类里面的方法和human类里 的方法构成了函数重载,编译过程中,知道调用的是哪个方法,这就是静态多态
动态多态
animal里的方法和human里的方法一模一样,通过不同的变量来分别调用它们,这个过程编译过程中不知道会调用哪个,比如控制台输入不同的变量来调用不同的方法,所以称为动态多态