基类指针和子类指针之间的相互赋值
(1)将子类指针赋值给基类指针时,不需要进行强制类型转换,c++编译器将自动进行类型转换。因为子类对象也是一个基类对象。
(2)将基类指针赋值给子类指针时,需要进行强制类型转换,c++编译器将不自动进行类型转换。因为基类对象不是一个子类对象。子类对象的自增部分是基类不具有的。(强制转换告诉编译器为对象增加子类所特有的部分)
多态
最常见的用法就是声明一个基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。如果没有使用虚函数的话,即没有利用c++多态性,则利用基类指针调用相应的函数的时候,将总被限制在基类函数本身,而无法调用到被重写过的函数。
实用场景:
比如控制一辆小车运动,在基类中定义了一个控制算法,但制定控制策略时,会根据不同的情况确定不同的行走方案,所以会在基类中定义一个虚函数contor1(),在各个子类中对虚函数control1进行不同实现以适应不同场景
例子
#include <iostream>
using namespace std;
class A
{
public:
virtual void Debug(){cout<<"base"<<endl;}
void fun1(){cout<<"base fun1"<<endl;}
void add(){cout<<"1+1"<<endl;}
};
class B:public A
{
public:
void Debug(){cout<<"child"<<endl;}
void fun1(){cout<<"child fun1"<<endl;}
void fun2(){cout<<"child fun2"<<endl;}
};
void main()
{
A* a;//声明一个基类指针a
a=new B;//这里将基类指针强制转换为了子类指针类型
a->Debug();//输出child,这里指针指向了虚函数 Debug,实际调用的就是其在子类B中的实现。
a->fun1();//输出base fun1,这里指针指向了基类的函数fun1,因为基类的fun1不是虚函数,所以就不会指向子类中的同名函数fun1
//a->fun2();//这样写就是错误的,基类指针能指向的函数只能是基类中存在的函数,基类不存在fun2,所以这样写就是错误的
B* b1=new B;//声明一个子类指针b1并初始化
b1->add();//输出1+1,可以看到子类指针可以指向基类中的函数add(),这个函数在子类B中并没有
b1->fun1();//输出child fun1,这里指针指向了基类的函数fun1,因为基类的fun1不是虚函数,所以就不会指向子类中的同名函数fun1
}