C++类对象大小的计算(二)含有虚函数类大小计算

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

前一篇文章《C++类对象大小的计算(一)常规类大小计算》初步介绍类大小计算后,我们继续来讨论含有虚函数时类的大小。

以下内存测试环境为Win7+VS2012,操作系统为32位

五、包含虚函数的类

        包含虚函数的类,对象生成时,会在类对象当中插入一个指针,这个指针称做虚函数表指针,简称虚表指针(vPtr)。该指针指向一个虚函数表(简称虚表),虚函数表中存储了虚函数的入口地址。基类当中有虚函数时,会产生该虚函数表;创建基类对象,对象中的vPtr会指向该表;调用虚函数时,是通过vPtr在此表当中寻找函数入口地址的。

        当派生类继承含有虚函数的子类时,会复制一份虚函数表,派生类如果有与基类中虚函数同名的虚函数,会在虚函数表中覆盖原来基类的虚函数;如果虚函数不重名,只会在虚函数表中增加一个函数入口。这种机制实现了类的多态。

如下面的例子:

#include <iostream>
using namespace std;

class A {
public:
	A(int x=0) {
		cout<<"A"<<x<<endl;
	}
	void printA() {
		cout<<"Hello A";
	}
};
class B :public A{
public:
	B(int x=0) {
		cout<<"B"<<x<<endl;
	}
	virtual void printB() {
		cout<<"Hello B";
	}
};

class C : public B{
public:
	C() {
		cout<<"C"<<endl;
	}
	virtual void printC() {
		cout<<"Hello C";
	}
};

int main() {
	A a;
	B b;
	C c;
	cout<<"size of a:"<<sizeof(a)<<endl;
	cout<<"size of b:"<<sizeof(b)<<endl;
	cout<<"size of c:"<<sizeof(c)<<endl;
	return 0;
}

VS类结构图:




运行结果为:


        类A没有虚函数,因此大小仍然是1。类B因为有虚函数,其对象当中包含了一个vPtr指针,指针指向类B的虚函数表(假设为vTB),该表中存储了printB的入口地址,因此大小为4。类C因为继承了类B,也就复制了vTB(设为vTC),其对象中也就包含了指向vTC的虚表指针,该虚表中除了有printB的入口地址外,还包含了printC的入口地址,因此,类C对象大小为4。

        考虑另一种情况,类C同时继承了类A、B,类A、B当中都有虚函数。如下面的例子:
#include <iostream>
using namespace std;

class A {
public:
	A(int x=0) {
		cout<<"A"<<x<<endl;
	}
	virtual void printA() {
		cout<<"Hello A";
	}
};
class B {
public:
	B(int x=0) {
		cout<<"B"<<x<<endl;
	}
	virtual void printB() {
		cout<<"Hello B";
	}
};

class C : public B, public A{
public:
	C() {
		cout<<"C"<<endl;
	}
	void printC() {
		cout<<"Hello C";
	}
};

int main() {
	A a;
	B b;
	C c;
	cout<<"size of a:"<<sizeof(a)<<endl;
	cout<<"size of b:"<<sizeof(b)<<endl;
	cout<<"size of c:"<<sizeof(c)<<endl;
	return 0;
}
VS类结构图:



运行结果为:
类A、B对象的大小按照上面所说的内存很好理解。类C因为同时继承了类A、B,因此就复制了两个虚函数表,也就有了两个vPtr,所以大小为8。如果类C有虚函数,也会放在其中一张虚函数表当中,不会再增加对象大小。
        含有成员变量时,按照《C++类对象大小的计算(一)常规类大小计算》所讲内容加上相应的大小即可。

        下面的文章《C++类对象大小的计算(三)含有虚函数、虚继承类大小计算》会讨论增加虚继承时,类对象的大小。
C++所占内存大小计算 C++所占内存大小计算 转载时请注明出处和作者联系方式 文章出处:http://blog.csdn.net/chenchong08 作者联系方式:vision_chen@yeah.net 说明:笔者的操作系统是32位的。 class A {}; sizeof( A ) = ? sizeof( A ) = 1 明明是空,为什么编译器说它是1呢? 空同样可以实例化,每个实例在 阅读详情

相关推荐

C++ sizeof 计算大小 虚函数 虚继承 虚基 虚函数

文章目录c++大小计算关于/对象大小计算一.简单情况的计算.空大小三.含有虚函数成员(1)在派生中不对基虚函数进行覆盖,同时派生中还拥有自己的虚函数在派生中对基虚函数进行覆盖(3)多继承:无虚函数覆盖(4)多重继承,含虚函数覆盖四.虚继承的情况 c++大小计算 c++所占的大小计算并没有想象中那么简单,因为涉及到虚函数成员,静态成员,虚继承,多继承以及空等,不同情况有对应的计算方式,在此对各种情况进行总结。 首先要明确一个概念,平时所声明的只是一种型定义,它本身是没

neninee的博客 2942

大小以及虚函数

一、大小 一个中,如果什么都没有,那么它所占的字节为1,如果在中添加了一个函数(虚函数),那么它的大小还是1,而如果是虚函数,那么对于32位系统来说是4字节,对于64位系统来说是8字节。 虚函数 中函数前有virtual这关键字,则此函数为虚函数。 class Base { public: virtual ~Base(); } Base::~Base(); 三、虚函数表 Base中存在虚函数,A继承Base,那么这两个都存在一个虚函数表。 class A : public Bas

DefiniteGoal的博客 1488

关于类对象大小的 sizeof 计算问题

之前看了很多关于类对象大小问题的计算,今天闲着没事就来整理整理,写写自己的看法。首先,来看看一个只有构造函数和析构函数的空:#include using namespace std;class Base{public: Base(); ~Base();};int main(int argc, char *argv[]){ cout << siz

iT2afL0rd's Blog 7096

C++类对象大小计算()含有虚函数、虚继承大小计算

前一篇文章《C++类对象大小计算()常规大小计算》初步介绍大小计算后,我们继续来讨论含有虚函数大小

日积月累 2512

C++虚继承下带有虚函数大小(含多重虚继承,虚继承后完全覆盖等复杂情况)

带有虚函数的虚继承的对象模型比较复杂,所以来整理一下。以下讨论均在visual studio2017以及64位环境的前提下进行; 1.带有虚函数 class A { public: int a_; virtual void foo1() { cout << "A1" << endl; } virtual void foo2() { cout <<...

chczy1的博客 1134

怎么计算C++继承 虚函数 虚继承

真空 C++代码 class CNull   {      };    长度:1   内存结构:   ??   评注:长度其实为0,这个字节作为内容没有意义,可能每次都不一样。   、空 C++代码 class CNull2   {   public:     CNull2(){printf("Construct/n");}     ~CNul

yishuige的专栏 446

含有虚函数sizeof大小

#include using namespace std; class Base1{ virtual void fun1(){} virtual void fun11(){} public: virtual ~Base1(); }; class Base2{ virtual void fun2(){} }; class DerivedFromOne:

芝兰生于深谷,不以无人而不芳 4146

C++ 类对象大小计算含有虚函数

五、包含虚函数         包含虚函数,对象生成时,会在类对象当中插入一个指针,这个指针称做虚函数表指针,简称虚表指针(vPtr)。该指针指向一个虚函数(简称虚表)虚函数表中存储了虚函数的入口地址。基当中有虚函数时,会产生该虚函数表;创建基类对象,对象中的vPtr会指向该表;调用虚函数时,是通过vPtr在此表当中寻找函数入口地址的。         当派生继承含有虚函数的子

跬步千里,窥叶知秋 1161

C++的存储及类对象内存结构

本文分两部分,前半部分讲的存储后半部分讲的内存结构。 C++的存储 c++中最重要的就是,那么一个的对象,它在内存中如何存储的?它占 内存中多少个字节? 首先确定的构成: 1,数据成员:可以是内置型,型。 2,函数成员:虚函数,非虚函数 1)数据成员 内置型对齐原则 内置型就是常用的:char,short,long,int,float,double. 这些内

fenxinzi557的博客 2万+

c++大小计算

c++所占的大小计算并没有想象中那么简单,因为涉及到虚函数成员,静态成员,虚继承,多继承以及空等,不同情况有对应的nisan方式,在此对各种情况进行总结。 首先要明确一个概念,平时所声明的只是一种型定义,它本身是没有大小可言的。 我们这里指的大小,其实指的是的对象所占的大小。因此,如果用sizeof运算符对一个型名操作,得到的是具有该型实体的大小。关于/对象大小计算 首先,

rotation博客 3万+

C++虚函数继承的内存占用大小计算

前半部分转自https://www.cnblogs.com/SeekHit/p/7570247.html 其中为32位字节对齐,后半部分给出自己的理解。 字节对齐的原理见链接https://www.cnblogs.com/0201zcr/p/4789332.html(注意64位系统虚函数指针占8字节,32位占4字节) 计算一个类对象大小时的规律: 1、空、单一继承的空、多重继承的空...

qq_31673283的博客 3592

C++虚函数表、虚继承,大小

C++虚函数表所占的大小?有虚函数的对象比没有虚函数的对象所占字节大小有区别吗?虚继承、虚函数继承中具体大小计算;构造函数里调用虚函数是实引用还是虚引用?

Yimi-依米 的博客 1950

C++一个类对象大小计算

计算一个类对象大小时的规律:  1、空、单一继承的空、多重继承的空所占空间大小为:1(字节,下同); 2、一个中,虚函数本身、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间的; 3、因此一个对象的大小≥所有非静态成员大小的总和(包括动态分配的变量...); 4、当中声明了虚函数(不管是1个还是多个),那么在实例...

banqiutu9162的博客 652

sizeof() 大小,空大小

一个的实例化对象所占空间的大小? 注意不要说大小,是的对象的大小. 首先,大小是什么?确切的说,只是一个型定义,它是没有大小可言的。 用sizeof运算符对一个型名操作,得到的是具有该型实体的大小。 如果 Class A; A obj; 那么sizeof(A)==sizeof(obj) 那么sizeof(A)大小和成员的大小总和是什么关系呢,很简单,一个对象的大小大于等于所有

liu_qiqi的专栏 2万+

大小计算

类对象大小 确切的说,只是一个型定义,它是没有大小可言的。 用sizeof运算符对一个型名操作,得到的是具有该型实体的大小(注意不要说大小,是的对象的大小.) C++标准规定大小不为0,空大小为1,当不包含虚函数和非静态数据成员时,其对象大小也为1。 如果在中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针指向虚函数表VTab...

weixin_43831728的博客 1714

C++大小

c++所占的大小计算并没有想象中那么简单,因为涉及到虚函数成员,静态成员,虚继承,多继承以及空等,不同情况有对应的计算方式,在此对各种情况进行总结。 首先要明确一个概念,平时所声明的只是一种型定义,它本身是没有大小可言的。 我们这里指的大小,其实指的是的对象所占的大小。因此,如果用sizeof运算符对一个型名操作,得到的是具有该型实体的大小。 关于/对象大小计算 首先,大小计算遵循结构体的对齐原则 大小与普通数据成员有关,与成员函数和静态成员无关。即普通成员函数,静态成员函

GreedySnaker的博客 1385

c++大小(涵盖继承 虚继承 虚函数表)

涉及到c++中求大小时需要特别注意一下几点 1.为的非静态成员数据的大小之和. 2.有编译器额外加入的成员变量的大小,用来支持语言的某些特性(如:指向虚函数的指针、虚继承、多重继承). 3.为了优化存取效率,进行的边缘调整. 4.  与中的构造函数,析构函数以及其他的成员函数无关.  5.  私有继承,会去继承之前的私有成员变量么? 会...在内存中仍然分配

水滴石穿 3486

C++类对象大小计算

()常规大小计算 C++类对象计算需要考虑很多东西,如成员变量大小,内存对齐,是否有虚函数,是否有虚继承等。接下来,我将对此举例说明。 以下内存测试环境为Win7+VS2012,操作系统为32位 一、完全空 [cpp]view plaincopy #include<iostream> usingnamespace...

daru9708的博客 482
上一篇: C++类对象大小的计算(一)常规类大小计算
下一篇: C++类对象大小的计算(三)含有虚函数、虚继承类大小计算
大空新一
博客等级 码龄17年 75粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值