• 静态联编动态联编
  • 静态多态(就是函数重载)和动态多态
  • 静态多态:函数重载,运算符重载
  • 动态多态:
  • //先有继承关系
  • //父类中有虚函数,子类重写父类中的虚函数
  • //父类的指针或引用 指向子类的对象
  • 静态多态在编译阶段绑定地址,地址早绑定,静态联编
  • 动态多次在运行阶段绑定地址,地址晚绑定,动态联编
  • 多态原理
  • 当父类写了虚函数后,类内部结构发生改变,多了一个vfptr
  • vfptr 虚函数表指针 ---- > vftable 虚函数表
  • 虚函数表内部记录着 虚函数的入口地址
  • 当父类指针或引用指向子类对象,发生多态,调用是时候从虚函数中找函数入口地址
  • 虚函数 关键字 virtual
  • 利用指针的偏移调用 函数
  • ((void()()) ((int )(int *)animal)) ();
  • typedef void( __stdcall *FUNPOINT)(int);
  • (FUNPOINT (((int)(int)animal + 1)))(10);

49. 静态联编动态联编及多态原理_虚函数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Animal
{
public:
	//虚函数
	virtual void speak()
	{
		cout << "动物在说话" << endl;
	}

	virtual void eat(int a )
	{
		cout << "动物在吃饭" << endl;
	}
};

class Cat :public Animal
{
public:
	void speak()
	{
		cout << "小猫在说话" << endl;
	}

	void eat(int a)
	{
		cout << "小猫在吃饭" << endl;
	}
};

class Dog :public Animal
{
public:
	void speak()
	{
		cout << "小狗在说话" << endl;
	}
};


//动态多态产生条件:
//先有继承关系
//父类中有虚函数,子类重写父类中的虚函数
//父类的指针或引用  指向子类的对象

//对于有父子关系的两个类  指针或者引用 是可以直接转换的
void doSpeak(Animal & animal) //Animal & animal = cat;
{
	//如果地址早就绑定好了,地址早绑定,属于静态联编
	//如果想调用小猫说话,这个时候函数的地址就不能早就绑定好,而是在运行阶段再去绑定函数地址,属于地址晚绑定,叫动态联编
	animal.speak(); 

}

void test01()
{
	Cat cat;
	doSpeak(cat);

	Dog dog;
	doSpeak(dog);
}




void test02()
{
	//cout << "sizeof  Animal = " << sizeof (Animal) << endl;

	Animal * animal = new Cat;
	//animal->speak();
	// *(int *)animal 解引用到虚函数表中
	// *(int *)*(int *)animal 解引用到函数speak地址

	//调用猫说话
	((void(*)()) (*(int *)*(int *)animal)) ();


	//C/C++默认调用惯例  __cdecl
	//用下列调用时候 真实调用惯例  是 __stdcall
	//调用猫吃饭
	typedef void( __stdcall *FUNPOINT)(int);

	(FUNPOINT (*((int*)*(int*)animal + 1)))(10);
}


int main(){
	//test01();
	test02();

	system("pause");
	return EXIT_SUCCESS;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.