虚函数笔记知识

一个class的data member可以表现这个class在程序执行时的某种状态。Nonstatic data member放置的是“个别的class object”感兴趣的数据,static data member则放置的是“整个class”感兴趣的数据,其中不管class创建出多少个objects,static data member永远只存在一份实例,但是一个template class的static data members的行为稍有不同。

3.1 虚函数表位置分析

类:如果类中有虚函数的话,那么这个类就会生成虚函数表
类对象:其有一个指针,这个指针(vptr)会指向这个虚函数表的开始地址
类中元素

// 验证虚函数表的位置
class A {
	public:
		int i;
		virtual void testfunc() {}; //虚函数
};
int main() {
	A aobj; //创建一个A的对象
	int ilen = sizeof(aobj); //ilen表示对象aobj的字节大小

	char* p1 = reinterpret_cast<char*>(&aobj);
	char* p2 = reinterpret_cast<char*>(&(aobj.i));
	if (p1 == p2) { //如果相同,那么说明aobj.i的地址和aobj相同
		cout << "i在对象aobj内存布局的上边" << endl;
	} else {
		cout << "vptr在对象aobj内存布局的上边" << endl;
	}
	return 0;
}

打印结果为虚函数表指针在对象内存的开头

3.2 继承关系作用下虚函数的手工调用

class Base {
	public:
		virtual void f() { cout << "Base::f()" << endl; }
		virtual void g() { cout << "Base::g()" << endl; }
		virtual void h() { cout << "Base::h()" << endl; }
};
class Derive : public Base {
	public:
		virtual void g() { cout << "Derive::g()" << endl; }
};
int main() {
	//继承关系作用下虚函数的手工调用
	cout << sizeof(Base) << endl;
	cout << sizeof(Derive) << endl;
	
	Derive *d = new Derive(); //派生类指针
	long *pvptr = (long*)d; //指向对象的指针d转成了long*类型
	long *vptr = (long*)(*pvptr); //(*pvptr)表示pvptr指向的对象,也就是Derive本身,也代表着虚函数表指针地址;
	//打印虚函数地址,实际是三个虚函数
	for (int i = 0; i<3; ++i) {
		printf("vptr[%d] = 0x:%p\n", i, vptr[i]);
	}
	
	typedef void(*Func)(void); //定义一个函数指针类型
	Func f= (Func)vptr[0]; //f就是函数指针变量,vptr[0]是指向第一个虚函数的
	Func g= (Func)vptr[1];
	Func h= (Func)vptr[2];
		
	f();
	g();
	h();
	//打印父类的虚函数依次类推
	return 0;
}

3.3 虚函数表分析

3.4 “继承”与Data Member

3.5 对象成员的效率

3.6 指向Data Members的指针

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

黑字。

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

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

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

打赏作者

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

抵扣说明:

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

余额充值