父类子类指针
类的重载与重写
方法重载(overload):判断方法重载的方法主要是根据方法的参数不同来判定;
- 必须是同一个类
- 方法名(也可以叫函数)一样
- 参数类型不一样或参数数量不一样
- 方法重载的返回值的类型可以不同
方法的重写(override)两同两小一大原则:方法重写的返回值类型需要相同,重写就是子类继承了父类的方法,并在此方法上重写属于自己的特征,既然是继承过来的,那么它的返回值类型就必须要相同
方法名相同,参数类型相同,返回值相同,
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。
父类与子类指针
class A
{
public:
void FuncA()
{
printf( "FuncA called\n" );
}
virtual void FuncB()
{
printf( "FuncB called\n" );
}
};
class B : public A
{
public:
void FuncA()
{
A::FuncA();
printf( "FuncAB called\n" );
}
virtual void FuncB()
{
printf( "FuncBB called\n" );
}
};
void main( void )
{
B b;
A *pa;
// 父类指针指向子类对象,只能指向子类对象中的父类部分,包括子类中指向虚表的_vptr,所以调用虚表是调用子类的,就分析子类对象虚表中指的是哪个函数就行了
pa = &b; // 这里不是对指针pa强制类型转换成A* ,而是对象b自动提升为A的对象。**并且这种情况下,子类不能有父类没有定义的方法。**
A *pa2 = new A;
pa->FuncA();
delete pa2;
}
上述代码用基类指针指向子类对象,为动态绑定,此时调用普通重写方法时,会调用父类中的方法。而调用被子类重写虚函数时,会调用子类中的方法。动态绑定所适用的函数必须是虚函数。子类中被重写的虚函数的运行方式是动态绑定的。
问:如果一个B* 的指针再强制类型转换成A*,会访问谁?基类的FuncA和子类的FuncB
当父类子类有同名非虚函数的时候,调用的是转换后的指针类型的函数;
当父类子类有同名虚函数的时候呢,调用的是指针转换前指向的对象类型的函数。
1.当自己的类指针指向自己类的对象时,无论调用的是虚函数还是实函数,其调用的都是自己的:
2.当指向父类对象的父类指针被强制转换成子类指针时候,子类指针调用函数时,只有非重写函数是自己的,虚函数是父类的;
3.当指向子类对象的子类指针被强制转换成父类指针的时候,也就是父类指针指向子类对象,此时,父类指针调用的虚函数都是子类的,而非虚函数都是自己的;