概念:多态指同一个实体同时具有多种形式。它是面向对象程序设计(OOP)的一个重要特征。
多态的两个条件:
1.父类的指针或引用
2.调用的成员函数必须是虚函数的重写
1.父类的指针或引用
2.调用的成员函数必须是虚函数的重写
构成多态 ----->跟指向的对象有关
不构成多态 ----->跟指针的类型有关
不构成多态 ----->跟指针的类型有关
代码块:
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<stdio.h>
using namespace std;
class base
{
public:
base(int a = 1, int b = 2, int c = 3)
: pub(a)
, pro(b)
, pri(c)
{
cout << "base()" << endl << endl;
}
~base()
{
cout << "~base()" << endl << endl;
}
virtual void dis()//加了关键字virtual,dis就成了虚函数
{
cout << "base::dis() ";
cout << "pub=" << pub;
cout << " pro=" << pro;
cout << " pri=" << pri << endl << endl;
}
void func()//同上,虚函数
{
cout << "base::func ";
pub *= 2;
pro *= 2;
pri *= 2;
cout << "pub=" << pub;
cout << " pro=" << pro;
cout << " pri=" << pri << endl << endl;
}
int pub;
protected:
int pro;
private:
int pri;
};
class Derive :public base
{
public:
Derive(int x = 4, int y = 5,int z=6)
: _pub(x)
, _pro(y)
, _pri(z)
{
cout << "Derive()" << endl;
}
~Derive()
{
cout << "~Derive()" << endl;
}
void dis()//基类中声明为virtual,那么在所有的派生类中该函数都是virtual,而不需要再显式地声明为virtual。
{
cout << "Derive::dis() ";
cout << "_pub=" << _pub;
cout << " _pro=" << _pro;
cout << " _pri=" << _pri << endl << endl;
}
void func()
{
cout << "Derive::func() ";
_pub *= 10;
_pro *= 10;
_pri *= 10;
cout << "_pub=" << _pub;
cout << " _pro=" << _pro;
cout << " _pri=" << _pri << endl << endl;
}
int _pub;
protected:
int _pro;
private:
int _pri;
};
void Test()//析构函数只在函数体结束时候调用,所以在main函数里声明不好看到析构函数
{
base b;
Derive d;
base*pb = &d;//父类指针指向子类对象---->条件一
Derive*pd = &d;//子类指针指向子类对象
pb->dis();//由于dis()是虚函数,即构成重写------->条件二 构成多态看对象
pd->dis();
pb->func();//func()不是虚函数,即构成隐藏 不构成多态看指针
pd->func();
cout << "sizeof(b)=" << sizeof(b) << endl;
cout << "sizeof(d)=" << sizeof(d) << endl << endl;
}
int main()
{
Test();
system("pause");
return 0;
}
运行结果截图:

下面了解一下
静态联编和动态联编:
(1)静态联编
完成静态联编的工作是在编译阶段完成了,主要实现的目标是在编译阶段就确定了函数调用和与执行该操作相关的代码之间的联系,是在程序运行前就已经完成的工作,称为早期联编,这种确定关系的过程叫做静态束定。静态联编的这种确定函数调用是基于指向对象的指针或引用的类型实现的,所以效率较高,但是灵活性较差。
静态联编也叫做编译时多态,主要实现形式是 通过函数重载和运算符重载来实现的,函数重载就是在一个程序中,函数名相同,但是参数列表不同,包括参数个数或者参数类型,或者两者都不同,这样的方式就是函数重载。
(2)动态联编
完成动态联编的阶段是在程序运行阶段,编译阶段是无法确定函数调用的,在运行的时候根据具体情况来确定到底调用哪个函数,这种联编称为晚期联编或动态束定。动态联编是 通过多态来实现的,对于成员函数的选择是基于对象的类型,根据不同的对象类型确定调用哪个成员函数,给出不同编译结果。C++中一般使用的是静态联编,但是涉及到虚函数的时候用到的就是动态联编。动态联编的特点是灵活性大,但是效率低。
(1)静态联编
完成静态联编的工作是在编译阶段完成了,主要实现的目标是在编译阶段就确定了函数调用和与执行该操作相关的代码之间的联系,是在程序运行前就已经完成的工作,称为早期联编,这种确定关系的过程叫做静态束定。静态联编的这种确定函数调用是基于指向对象的指针或引用的类型实现的,所以效率较高,但是灵活性较差。
静态联编也叫做编译时多态,主要实现形式是 通过函数重载和运算符重载来实现的,函数重载就是在一个程序中,函数名相同,但是参数列表不同,包括参数个数或者参数类型,或者两者都不同,这样的方式就是函数重载。
(2)动态联编
完成动态联编的阶段是在程序运行阶段,编译阶段是无法确定函数调用的,在运行的时候根据具体情况来确定到底调用哪个函数,这种联编称为晚期联编或动态束定。动态联编是 通过多态来实现的,对于成员函数的选择是基于对象的类型,根据不同的对象类型确定调用哪个成员函数,给出不同编译结果。C++中一般使用的是静态联编,但是涉及到虚函数的时候用到的就是动态联编。动态联编的特点是灵活性大,但是效率低。
动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式是指向基类的指针->虚函数(参数列表)或者基类对象的引用名.虚函数(参数列表)
OVER...