多态的深层理解
多态的实现效果:
多态:同样的调用语句有不同的表现形式,也就是说里面具体实现的代码不同。
多态实现的三个条件:
有继承、virtual重写、父类指针指向子类指针。
多态的理论基础:
动态联编:
编译程序在编译阶段并不能确切地知道将要调用的函数,只有在程序执行时才能确定将要调用的函数,为此要确切地知道将要调用的函数,要求联编工作在程序运行时进行, 这种在程序运行时进行的联编工作被称为动态联编,或动态束定,又叫晚期联编;C++规定:动态联编是在虚函数的支持下实现的;
静态联编:
是指联编工作是在程序编译连接阶段进行的,这种联编又称为早期联编;因为这种联编是在程序开始运行之前完成的;
在程序编译阶段进行的这种联编又称静态束定;在编译时就解决了程序中的操作调用与执行该操作代码间的关系,确定这种关系又被称为束定;编译时束定又称为静态束定;
多态的重要意义:
是设计模式的基础。
实现多态的理论基础:
函数指针做函数参数。
c++中多态的实现原理:
在类中声明虚函数时,编译器会在类中生成一个虚函数表。
虚函数表是一个存储类成员函数指针的数据结构。
虚函数表是编译器自动生成并维护的。
virtual成员函数会被编译器放入虚函数表中。
存在虚函数时,每个对象中都有一个指向虚函数表的指针 (vptr 指针)
例子程序:
/*************************************************************************
> File Name: main.cpp
> Author: caiyaodeng
> Mail: caiyaodeng@gmail.com
> Created Time: Tue 12 Jan 2016 10:11:28 PM EST
************************************************************************/
#include<iostream>
using namespace std;
class Base {
public:
Base (){
cout <<"Base structure !" << endl;
toPrintf ();
}
~Base (){
cout <<"Base distruct !" << endl;
}
virtual void toPrintf (){
cout << "Base Printf !" << endl;
}
};
class Drive :public Base{
public:
Drive (){
cout << "Dirve structure !" << endl;
}
~Drive (){
cout <<"Drive distruct !" << endl;
}
virtual void toPrintf (){
cout << "Drive Printf !" << endl;
}
};
int main () {
//Base *pBase = new Base ();
Drive *pDrive = new Drive ();
//delete pBase;
//pBase = NULL;
pDrive->toPrintf ();
delete pDrive;
pDrive = NULL;
return -1;
}
#include <iostream>
using namespace std;
/**
说明:基类*/
class base {
public:
virtual
void printf () = 0{
cout << "我是基类!" << endl;
}
};
/**
说明:子类_1*/
class dirve_1 :public base { //1.继承
public:
/**
说明:2.虚函数重写*/
virtual
void printf () {
cout << "我是子类_1!" << endl;
}
};
/**
说明:子类_2*/
class dirve_2 :public base { //1.继承
public:
/**
说明:2.虚函数重写*/
virtual
void printf () {
cout << "我是子类_2!" << endl;
}
};
/**
说明:搭建调用舞台*/
bool playShow (const base *pBase) {
const_cast <base *> (pBase)->printf ();
return true;
}
int main () {
dirve_1 objDrive_1;
dirve_2 objDrive_2;
playShow (&objDrive_1); //3.父类指针指向子类对象
playShow (&objDrive_2); //3.父类指针指向子类对象
system ("pause");
}
在这段代码中,如下图: