- 子类在定义对象时候,会调用子类的构造函数(子类的构造必须调用父类的构造)
- 虚继承 用来解决菱形继承问题,
一个父类的指针或引用,可以指向指向子类对象,但是调用这个指向子类对象的父类指针进行访问子类对象时候,依然只能访问父类成员
一般用作传参数
要想用父类指针访问子类中新写的成员,必须使用虚函数 vfptr (虚表)
虚函数使用过程:通过父类指针/父类引用---->找到父类虚标----->找到对应的函数----->调用函数
/|\
|
子类重写覆盖虚函数
- 父类指针指向子类对象时候,依然会调用父类的析构,什么类型的指针,就调用其类析构
- 如果父类有虚函数,建议把析构同样写成虚析构
多态(一种形式,对应不同的状态)
- 父类的 指针/引用 可以指向子类对象
class Father{
y=0;
void func2(){}
}
class Son: public Father{
x=0;
void func(){}
void func2(){}
}
int main()
{
Son myson;
Father *p; // 父类指针
*p = &myson; // 父类指针可以指向子类对象
p->x; // 调用myson中的x
p->func(); // 调用myson中的func()函数
p->func2(); // 调用myson中继承自Father中的func()函数
//父类指针指向子类的对象,优先调用的依然是父类的函数
}
虚函数
- 父类的指针没法访问子类的其他内容。f’d’r’r’r’r’r’r’r’r’r’r’r
- 父类的指针可以接收子类对象的地址
- 用 父类指针/引用 作为形参 可以接受任意类型的子类对象
- 根据子类对象的不同,调用不同的函数 /多态
- 如果想用父类指针或者父类引用 调用子类新写函数,那么必须用到虚函数
- 子类重写父类的虚函数,也是一个虚函数
class Father{
y=0;
virtual void fun2(){}
}
class Son: public Father{
x=0;
void func2(){} // 子类重写父类的虚函数,这里也是一个虚函数,前面可以加virtual,也可以不加
void func(){}
}
int main()
{
Son myson;
Father *p; // 父类指针
*p = &myson; // 父类指针可以指向子类对象
p->x; // 调用myson中的x
p->func(); // 调用myson中的func()函数
}
-
子类重写父类的虚函数,也是一个虚函数
-
纯虚函数不可以访问,定义一个虚函数,会定义一个虚表,用来记录虚函数的内存地址
-
隐藏,子类重写父类的函数,父类函数会被隐藏
-
覆盖,子类重写父类的虚函数,父类虚函数会被覆盖
-
纯虚函数是一个接口,需要子类去实现其功能