目录标题
1. 虚函数
1)成员函数前面加virtual
关键字,函数就是虚函数。
2)virtual
关键字只用在类定义的函数声明里面,写函数体时不用。
3)构造函数和静态函数不能是虚函数。原因这两函数没有对象。虚函数能参与多态。
4)虚函数与普通函数的区别:虚函数可以参与多态,普通的成员函数不能。
2. 多态
2.1 多态的表现形式1
1)派生类的指针可以赋值给基类指针。base * pb = & d;
2)通过基类指针调用基类和派生类中同名的虚函数时。若该指针指向一个基类的对象,那么调用是基类的虚函数;若该指针指向一个派生类的对象,那么被调用的是派生类的虚函数。
2.2 多态的表现形式2
1)派生类的对象可以赋值给基类的引用:base & br = d;
2)通过基类引用调用基类和派生类中同名的虚函数时。若该引用引用的是一个基类的对象,那么调用是基类的虚函数;若该引用引用的是一个派生类的对象,那么被调用的是派生类的虚函数。
2. 多态的例子
3. 更多地多态例子
纯虚函数连函数体都没有。为什么不需要给Cshape
类编写面积和打印信息的函数呢?因为不存在Cshape
类的几何形体。
成员函数的实现如下:
用基类指针数组存放各个几何形体。基类指针指向派生类的对象。
语句pShape[i]->PrintInfo();
就是多态语句。
很关键的MyCompare
函数写法
4. 多态的有一例子
5. 构造函数和析构函数中调用虚函数
具体的例子:基类maclass
,有两个虚函数hello()
和bye()
。然后呢son
从class
派生而来,注意hello()
没有写virtual
,但也是虚函数,因为C++规定:派生类中和基类中虚函数同名同参数标的函数,不加virtual
也是虚函数。在son
的构造函数调用了hello()
,析构函数调用了bye()
。下一层派生类grandson
,hello()
也是虚函数,bye()
,构造函数grandson()
,析构函数~grandson()
。
6. 动态联编
Base
对象b
前四个字节放着的是Base
类对应的虚函数表的指针(地址),接下来才开始存放自己的成员变量i
,通过虚函数表的指针能够找到Base
类的虚函数表,虚函数表放的是Base
类的所有虚函数在内存里面的地址,通过这张表,有了虚函数的名字就可以查到某个虚函数在内存里面的地址,有了地址就可以调用这个函数。
7. 虚析构函数
遇到了实际的问题:基类的指针p
去指向派生类对象(new了一个),在程序执行操作后,会delete指针p
,此时不知道改使用基类还是派生类的析构函数。
8. 纯虚函数和抽象类
纯虚函数:没有函数体