多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphism),字面意思多种形状。
多态
多态性是面向对象程序设计的重要特性之一.所谓的多态就是指用同一个名字定义不同的函数,这些函数执行不同而又相似的操作,从而可以使用相同的方式来调用这些具有不同功能的同名函数.在C++中,用相同的函数名来标识这些函数,就可以达到用相同的接口访问不同功能的函数,从而实现”一个接口,多种方法”.
从实现角度看,多态分为两类:编译时的多态和运行时的多态.
编译时的多态是通过静态连编来实现的
运行时的多态是通过动态连编来实现的
连编就是把函数名和函数体的程序代码联系到一起的过程.
静态连编是在编译阶段完成的,系统进行实参和形参的匹配,同名函数重载根据参数差异进行区分,然后连编实现多态.
动态连编是在运行时实现的连编,当程序调用某一函数名时,才去寻找并联系其代码.
在C++中,编译时的多态主要通过函数重载和运算符重载实现,运行时的多态通过虚函数来实现.
虚函数
虚函数:类的成员函数前面加上virtual关键字,则这个成员函数称为虚函数.
格式如下:
Virtual 返回类型 函数名(形参表)
{ 函数体 }
虚函数重写:当在子类中声明了一个和父类完全相同的虚函数时,则称子类的这个函数重写(覆盖)了父类的虚函数(函数名,参数,返回值相同)
多态和类型无关,和对象有关
构成多态的两个条件:
- 虚函数的重写
- 父类的指针或者引用调用虚函数.
class A { public : A() { cout << "A()" << endl; } virtual void show() { cout << "A::show()" << endl; } }; class B:public A { public: B() { cout << "B()" << endl; } virtual void show() { cout << "B::show()" << endl; } }; void fun(A& p) { p.show(); } int main() { B pb; A pa; fun(pa); fun(pb); }

注意:如果父类成员函数写virtual而子类没有,构成多态.子类写了父类没有写,不构成多态.
总结:
1.派生类重写基类的虚函数实现多态,要求函数名、参数列表、返回值完全相同。协变除外)
2.基类中定义了虚函数,在派生类中该函数始终保持虚函数的特性。
3.只有类的成员函数才能定义为虚函数。
4.静态成员函数不能定义为虚函数。
5.如果在类外定义虚函数,只能在声明函数时加virtual,类外定义函数时不能加virtual。
6.构造函数不能为虚函数,虽然可以将operator=定义为虚函数,但是最好不要将operator=定义为虚函数,因为容易使用时容易引起混淆。
7.不要在构造函数和析构函数里面调用虚函数,在构造函数和析构函数中,对象是不完整的,可能会发生未定义的行为。
8.最好把基类的析构函数声明为虚函数。(why?另外析构函数比较特殊,因为派生类的析构函数跟基类的析构函数名称不一样,但是构成覆盖,这里是因为编译器做了特殊处理)
纯虚函数
在成员函数的形参后面加上=0,则成员函数是纯虚函数.包含纯虚函数的类叫做抽象类(也叫做接口类),抽象类不能实例化出对象.纯虚函数在派生类中重新定义以后,派生类才能实例化出对象.
友元和继承
友元关系不能继承.
继承和静态成员
基类定义了一个成员,则整个继承体系中也只有一个这样的成员.无论派生出多少个子类,都只有一个static实例.
例如:统计该体系产生了多少个对象.
多态的原理:
虚函数:为了重写.
本文详细介绍了C++中的多态性概念,包括其基本定义、实现方式以及虚函数的作用。探讨了多态性的两种形式——编译时多态和运行时多态,并通过示例代码展示了如何使用虚函数实现多态。
1467

被折叠的 条评论
为什么被折叠?



