C++ 虚函数的使用以及简单认识(自学笔记可能有错)

虚函数的作用

拥有 Virtual 关键字的函数称之为虚函数,虚函数和虚继承是不一样的,虚函数是实现多态思想的一个重要概念。虚函数的作用是实现动态绑定的,也就是说程序在运行的时候动态的的选择合适的成员函数。将基类的指针(引用也行)指向不同的对象,名称相同的成员函数会展现出不同的结果。

虚函数的使用

这里借鉴的博客园 唯一诺的文章,在此感谢 https://www.cnblogs.com/weiyouqing/p/7544988.html(文章网址)

#include <iostream>
using  namespace std;

class Parent
{
public:

	char data[20];
	void Function1();
	virtual void Function2();   // 这里声明Function2是虚函数

}parent;

void Parent::Function1()
{
	printf("This is parent,function1\n");
}

void Parent::Function2()
{
	printf("This is parent,function2\n");
}

class Child :public Parent
{
	void Function1();
	void Function2();

} child;

void Child::Function1()
{
	printf("This is child,function1\n");
}

void Child::Function2()

{
	printf("This is child,function2\n");
}


void fun(Parent & p)  //这是引用的方法
{
	p.Function1();
	p.Function2();
}


int main(int argc, char* argv[])
{
	Parent *p;  
	cout << "父类指针指向子类对象的情况" << endl;
    p = &child;        
	p->Function1();
	p->Function2();
	cout << "父类指针指向父类对象的情况" << endl;
	p = &parent;      
	p->Function1(); 
	p->Function2();   

	fun(child);
	fun(parent);
	return 0;

}

 

含有虚函数的类内部的布局初步了解

这里借鉴了CSDN 吃个椰子压压惊的文章,在此表示感谢 https://blog.csdn.net/lyztyycode/article/details/81326699

通过VS的工具观察类内部的结构。

#include <iostream>
using  namespace std;

class Parent   //父类
{
public:

	int a;
	virtual void Function1();
	virtual void Function2();   
	virtual void Function3();

}parent;

void Parent::Function1()
{
	printf("This is parent,function1\n");
}

void Parent::Function2()
{
	printf("This is parent,function2\n");
}

void Parent::Function3()
{
	printf("This is parent,function3\n");
}

class Parent2   //父类2
{
public:

	int a;
	virtual void Function1();
	virtual void Function2();
	virtual void Function3();

}parent2;

void Parent2::Function1()
{
	printf("This is parent,function1\n");
}

void Parent2::Function2()
{
	printf("This is parent,function2\n");
}

void Parent2::Function3()
{
	printf("This is parent,function3\n");
}


class Child :public Parent ,public Parent2  //子类
{
	virtual void Function1();
	virtual void Function5();

} child;

void Child::Function1()
{
	printf("This is child,function4\n");
}

void Child::Function5()

{
	printf("This is child,function5\n");
}

int main(int argc, char* argv[])
{

	return 0;

}

//下面是不同情况的子类内部空间布局


一般继承没有虚函数覆盖的情况
父类中有虚函数  Function1  Function2  Function3
子类中有虚函数  Function4  Function5
/*
1>class Child	size(8):
1>	+---
1> 0	| +--- (base class Parent)
1> 0	| | {vfptr}
1> 4	| | a
1>	| +---
1>	+---
1>
1>Child::$vftable@:
1>	| &Child_meta
1>	|  0
1> 0	| &Parent::Function1
1> 1	| &Parent::Function2
1> 2	| &Parent::Function3
1> 3	| &Child::Function4
1> 4	| &Child::Function5
1>
1>Child::Function4 this adjustor: 0
1>Child::Function5 this adjustor: 0
*/


一般继承有虚函数覆盖的情况
父类有虚函数 Function1 Function2 Function3
子类有虚函数 Function1 Function5
/*
1>class Child	size(8):
1>	+---
1> 0	| +--- (base class Parent)
1> 0	| | {vfptr}
1> 4	| | a
1>	| +---
1>	+---
1>
1>Child::$vftable@:
1>	| &Child_meta
1>	|  0
1> 0	| &Child::Function1
1> 1	| &Parent::Function2
1> 2	| &Parent::Function3
1> 3	| &Child::Function5
1>
1>Child::Function1 this adjustor: 0
1>Child::Function5 this adjustor: 0
*/



多继承但是父类虚函数没有被覆盖的情况
父类1有虚函数 Function1 Function2 Function3
父类2有虚函数 Function1 Function2 Function3
子类有虚函数  Function4 Function5
/*
1>class Child	size(16):
1>	+---
1> 0	| +--- (base class Parent)
1> 0	| | {vfptr}
1> 4	| | a
1>	| +---
1> 8	| +--- (base class Parent2)
1> 8	| | {vfptr}
1>12	| | a
1>	| +---
1>	+---
1>
1>Child::$vftable@Parent@:
1>	| &Child_meta
1>	|  0
1> 0	| &Parent::Function1
1> 1	| &Parent::Function2
1> 2	| &Parent::Function3
1> 3	| &Child::Function4
1> 4	| &Child::Function5
1>
1>Child::$vftable@Parent2@:
1>	| -8
1> 0	| &Parent2::Function1
1> 1	| &Parent2::Function2
1> 2	| &Parent2::Function3
1>
1>Child::Function4 this adjustor: 0
1>Child::Function5 this adjustor: 0
*/



多继承且父类虚函数有被覆盖的情况
父类1有虚函数 Function1 Function2 Function3
父类2有虚函数 Function1 Function2 Function3
子类有虚函数  Function1 Function5
/*
1>class Child	size(16):
1>	+---
1> 0	| +--- (base class Parent)
1> 0	| | {vfptr}
1> 4	| | a
1>	| +---
1> 8	| +--- (base class Parent2)
1> 8	| | {vfptr}
1>12	| | a
1>	| +---
1>	+---
1>
1>Child::$vftable@Parent@:
1>	| &Child_meta
1>	|  0
1> 0	| &Child::Function1
1> 1	| &Parent::Function2
1> 2	| &Parent::Function3
1> 3	| &Child::Function5
1>
1>Child::$vftable@Parent2@:
1>	| -8
1> 0	| &thunk: this-=8; goto Child::Function1
1> 1	| &Parent2::Function2
1> 2	| &Parent2::Function3
1>
1>Child::Function1 this adjustor: 0
1>Child::Function5 this adjustor: 0
*/
发布了9 篇原创文章 · 获赞 0 · 访问量 104

猜你喜欢

转载自blog.csdn.net/weixin_42148156/article/details/104077265