1.上课部分知识点:一个是默认构造函数在写了有参等其他类型的时候不会再自动提供了,所以最好自己写一个
再就是一个新的知识点:向上造型(似乎和多态有关)
以及
C++随笔:父类和子类指针的指向 - 知乎(不推荐)
里面最关键的部分:
(1)定义父类类型的指针p,指向子类类型(地址值为子类类型指针):这种做法是安全的,因为指针p是父类类型,只能访问父类中定义的成员,而子类继承了父类所有的成员,所以指针p不会出现非法访问。如果此时,p想访问子类特有函数,在语法上不被允许,因为p是父类类型指针,但可以在父类中声明虚函数,然后在子类重写,那么此时p在调用虚函数时,即可访问到子类重写的函数。
2. 多态的基本语法
多态分为两类:
静态多态:函数重载 和 运算符重载, 以及复用函数名(也就是我们不加virtual关键字的那种)
动态多态: 派生类 和 虚函数 实现运行时多态
静态多态和动态多态区别:
静态多态的函数地址早绑定 - 编译阶段确定函数地址
动态多态的函数地址晚绑定 - 运行阶段确定函数地址
#include
using namespace std;
class Animal
{
public:
virtual void speak()//虚函数实现地址晚绑定
{
cout << "Animal is speaking!" << endl;
return;
}
};
class Cat: public Animal
{
public:
void speak()
{
cout << "Cat is speaking!" << endl;
return;
}
};
void doSpeak(Animal & animal){
animal.speak();//这个函数的地址在上面加了虚函数以后不能提前确定
return;
}
void test01()
{
Cat cat1;
doSpeak(cat1);
return;
}
int main()
{
test01();
system("pause");
return 0;
}
注意上面Animal父类的speak函数如果没有加virtual,那么在doSpeak函数中通过Animal类型的引用调用的话,无论你传进去的是个猫还是狗,都不会调用猫狗自己的speak函数,而是调用它们父类的speak函数,也就是最后结果显示为Animal is speaking 这个叫做静态多态
而当加上了一个virtual了以后,根据"动态多态的地址晚绑定“,就会根据我传进去的动物类型来分别执行各自的speak函数。也就实现了动态多态
动态多态的满足条件:
1.要有继承关系
2.子类要重写父类的虚函数 (也就是上面代码中的speak函数)
注意这里是重写!而不是重载!
重写 函数返回值类型 函数名 参数列表 都完全相同
父类虚函数前面必须加virtual关键字,而子类在重写的时候可写可不写
动态多态的使用:
父类的指针或者引用 指向子类对象