静态绑定与动态绑定:
静态绑定
编译时就能确定一条函数调用语句要调用的函数
在程序编译时多态性体现在函数和运算符的重载上
动态绑定
运行时才能确定函数调用语句调用的函数
程序运行时的多态性通过继承和虚函数来体现
多态性的概念:
多态性是面向对象程序设计的重要特征之一
多态性概念:具有继承关系的类,其对象对同一个函数调用可以作出不同的响应
同一个函数调用——同一条函数调用语句
不同的响应——执行不同的函数
多态性的优点:
多态性有助于更好地对程序进行抽象
- 控制模块能专注于一般性问题的处理
- 具体的操作交给具体的对象去做
多态性有助于提高程序的可扩展性
- 可以把控制模块与被操作的对象分开
- 可以添加已定义类的新对象,并能管理该对象
- 可以添加新类(已有类的派生类)的新对象,并能管理该对象
虚函数:
虚函数的概念:在基类中冠以关键字 virtual 的成员函数
虚函数的定义:
函数类型 函数名称(参数列表);
如果virtual一个函数在基类中被声明为虚函数,则他在所有派生类中都是虚 函数(包括重定义函数)
只有通过基类指针或引用调用虚函数才能引发动态绑定(用基类指针指向派生类指针)
- 继承时,如果不需要重写父类的函数,则不会创建新的地址来存储函数,使用的就是父类的函数地址,如果需要重写,则会开辟新的地址来存储重写的这个函数
- 基类指针或引用调用虚函数,实现动态绑定(基类指针指向派生类指针)
虚函数的注意事项:
在类体系中访问一个虚函数时,应使用指向基类类型的指针或对基类类型的引用,以满足运行时多态性的要求。当然也可以像调用普通成员函数那样利用对象名来调用一个函数。
在派生类中重新定义虚函数时,必须保证该函数的值和参数与基类中的说明完全一致,否则就属于重载
若在派生类中没有重新定义虚函数,则该类的对象将使用其基类中的虚函数代码。
虚函数必须是类的一个成员函数,不能是友元,但它可以是另一个类的友元。虚函数不得是一个静态成员。
虚函数和重载函数的区别:
成员函数被重载需要在相同范围(同一个类中),而虚函数要求在不同的范围(一个在派生类,一个在基类)
重载函数要求函数有相同函数名称,并有不同的参数序列;而虚函数则要求函数名、返回值类型和参数序列完全相同
重载函数可以是成员函数或友员函数,而虚函数只能是成员函数
重载函数的调用是以所传递参数序列的差别作为调用不同函数的依据;虚函数是根据对象的不同去调用不同类的虚函数
虚函数在运行时表现出多态功能,这是C++的精髓;而重载函数则在编译时表现出多态性
纯虚函数:
在基类中不能给出有意义的虚函数定义,这时可以把它说明成纯虚函数,把它的定义留给派生类来做
定义纯虚函数:
class 类名{
virtual 返回值类型 函数名(参数表) = 0;
};
纯虚函数不需要实现
纯虚函数: virtual void fun( ) = 0
多继承: class A : public B public C
抽象类:
如果一个类中至少有一个纯虚函数,那么这个类被成为抽象类(abstract class)
抽象类存在的意义是作为其它类的基类,也叫抽象基类
主要作用:取若干类的共同行为,形成更清晰的概念层次。使用抽象类符合程序设计中的单选原则
- 抽象类不能用于直接创建对象实例,可以声明抽象类的指针和引用
- 可使用指向抽象类的指针支持运行时多态性
- 派生类中必须重写基类中的纯虚函数,否则它仍将被看作一个抽象类
虚析构函数
析构函数可以声明为虚函数
·delete 基类指针;
·程序会根据基类指针指向的对象的类型确定要调用的析构函数
·基类的析构函数为虚函数,所有派生类的析构函数都是虚函数
·构造函数不得是虚函数
·如果要操作具有继承关系的类的动态对象,最好使用虚析构函数。特别是在析构函数需要完成一些有意义的操作——比如释放内存时