c++虚函数和虚函数表

什么是虚函数?

用virtual 修饰的成员函数叫虚函数

  • 没有虚构造函数       

  • 不写虚函数,没有默认的虚函数

  • 虚函数对于类的影响:增加一个指针的内存

  • 虚函数的存储:虚函数表(了解内容:就是一个指针存储所有虚函数的首地址[函数指针],只有指针[4字节]可以操作一段内存)

  • 用来实现多态以及ADT(抽象数据类型)过程

普通函数不影响类的内存

class MM
{
public:
    void print() 
	{
		cout << "普通函数"<< endl;//普通函数不影响类的内存--->普通函数存在另一段内存中
	}
protected:

};

void testVirtual()
{
	//C语言不允许存在空的结构体,c++允许存在
	cout << sizeof(MM) << endl;/*(没有数据成员的)空的类或者结构体占用1字节   
                                  用1字节标识当前内存为结构体内存*/
}
int main() 
{
	testVirtual();
	return 0;
}
/*输出*/

1 

虚函数会影响类的内存

增加一个指针的内存,32位操作系统多4个字节 ,64位操作系统多8个字节

class MM
{
public:
	virtual void print1() 
	{
		cout << "虚函数1"<< endl;
	}
	/*virtual void print2()
	{
		cout << "虚函数2" << endl;
	}   无论多少个虚函数,所增加的字节都是一个指针的字节--->多了一个虚函数,还是4个字节
 所有的虚函数其实是用一个函数指针去存储的:把这个函数指针所指向的这一段内存称为虚函数表
    */
protected:
};
void testVirtual()
{
	cout << sizeof(MM) << endl;			
}
int main() 
{
	testVirtual();
	return 0;
}
/*输出*/

4 

小知识:空的类|结构体占1个字节,一旦有了数据,标识位就不存在了

class A
{
	int num;    //输出4而不是输出5   (4+1)
};
class B
{
    //用1字节标识当前内存为结构体内存
};
void testVirtual()
{

	cout << sizeof(A) << endl;
    cout << sizeof(B) << endl;
}
int main()
{
	testVirtual();
	return 0;
}

/*输出*/

4
1

了解虚函数表--->通过虚函数表的指针去访问数据|成员|函数

  • 所有的虚函数其实是用一个函数指针去存储的,把这个函数指针指向的这一段内存称为虚函数表 就是一个指针存储所有虚函数的首地址(虚函数函数名)<--->函数指针

  • 只有指针可以操作一段内存(4字节)

  • 一个类的对象,对象的内存,如果没有数据,第一个内存存的是虚函数表的指针(类似二维数组)

  • 没有数据,取对象的地址(二级指针),就是虚函数指针的地址,通过这种方式来访问

/*无论多少个虚函数,增加的字节就是一个指针的字节*/

通过虚函数表的理解去调用虚函数 

class MM
{
public:
	virtual void print1() 
	{
		cout << "虚函数1"<< endl;
	}	
    virtual void print2() 
	{
		cout << "虚函数2"<< endl;
	}	
protected:
};
void testVirtual()
{
//虚函数表 	
	MM mm;    //构建一个对象
	int** vptr = (int** )&mm;  //定义一个二级指针取对象的地址  强转类型
	typedef void(*PF)();       //函数指针类型定义别名
	PF func = (PF)vptr[0][0];  //强转类型把地址转为函数指针,访问第一个函数指针的地址

	func();   //通过虚函数表的函数指针调用第一个虚函数
	func = (PF)vptr[0][1];
	func();	  //调用第二个虚函数
}
int main() 
{
	testVirtual();
	return 0;
}
/*输出*/

虚函数1
虚函数2

虚函数可以在类中声明,在类外实现,类外不需要virtual修饰,只需要类名限定就可以了

class MM
{
public:
	virtual void print3();
		
protected:
};
void MM::print3() 
{
	cout << "虚函数3" << endl;
}
int main()
{
	MM mm;
	mm.print3();
	return 0;
}
/*输出*/

虚函数3
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuqiuyaq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值