c++全局类对象_C++ 类在内存中的存储方式(一)

说了这么久的 C++ 终于说到类了,还是从内存出发来讨论一下 C++ 的类在内存中的存储方式(之前写过一篇内存对齐的文章,类同样在一定程度上遵循内存对齐原则,不过比结构体复杂一下)

如有侵权,请联系删除,如有错误,欢迎大家指正,谢谢

0.空类

class Test {};Test t0;
cout << sizeof(t0) << endl;
// 运行结果:1

解释:

  • 空类,没有任何成员变量和成员函数,编译器是支持空类实例化对象的,对象必须要被分配内存空间才有意义,这里编译器默认分配了 1Byte 内存空间(不同的编译器可能不同)

1. 含有成员变量的类

// ====== 测试一 ======
class Test {
private:int i;char c;double d;
};Test t11;
cout << sizeof(t11) << endl;
// 运行结果:16// ====== 测试二 ======
class A{};class Test {
private:int i;char c;double d;A a;
};Test t12;
cout << sizeof(t12) << endl;
// 运行结果:24// ====== 测试三 ======
class A {
private:double dd;int ii;int* pp;
};class Test {
private:int i;A a;double d;char* p;
};Test t13;
cout << sizeof(t13) << endl;
// x86目标平台运行结果:40;x64目标平台下运行结果:48

解释:

  • 这里的类的内存对齐原则与前面写的结构体的内存对齐原则是一样的(不太了解的可以移步我之前的《C/C++中内存对齐问题的一些理解》查看)
  • 测试三中,32bit 目标平台寻址空间是 4Byte(32bit),所以指针是 4Byte的;64bit 目标平台寻址空间是 8Byte(64bit),所以指针是 8Byte
  • 另外,静态成员变量是在编译阶段就在静态区分配好内存的,所以静态成员变量的内存大小不计入类空间(不太了解C++内存分布的可以移步我之前写的《C/C++程序的内存分布》查看)

2.含有成员变量和成员函数的类

// ====== 测试一 ======
class Test {
private:int n;char c;short s;
};Test t21;
cout << sizeof(t21) << endl;
// 运行结果:8// ====== 测试二 ======
class Test {
public:Test() {}int func0() {return n;}friend int func1();int func2() const {return s;}inline void func3() {cout << "inline function" << endl;}static void func4() {cout << "static function" << endl;}~Test() {}private:int n;char c;short s;
};int func1() {Test t;return t.c;
}Test t22;
cout << sizeof(t22) << endl;
// 运行结果:8// ====== 测试三 ======
class Test {
public:Test() {}int func0() {return n;}friend int func1();int func2() const {return s;}inline void func3() {cout << "inline function" << endl;}static void func4() {cout << "static function" << endl;}virtual void func5() {cout << "virtual function" << endl;}~Test() {}private:int n;char c;short s;
};int func1() {Test t;return t.c;
}Test t23;
cout << sizeof(t23) << endl;
// x86目标平台运行结果:12;x64目标平台下运行结果:16

解释:

  • 因 C++中成员函数和非成员函数都是存放在代码区的,故类中一般成员函数、友元函数,内联函数还是静态成员函数都不计入类的内存空间,测试一和测试二对比可证明这一点
  • 测试三中,因出现了虚函数,故类要维护一个指向虚函数表的指针,分别在 x86目标平台和x64目标平台下编译运行的结果可证明这一点

总结

  • C++编译系统中,数据和函数是分开存放的(函数放在代码区;数据主要放在栈区和堆区,静态/全局区以及文字常量区也有),实例化不同对象时,只给数据分配空间,各个对象调用函数时都都跳转到(内联函数例外)找到函数在代码区的入口执行,可以节省拷贝多份代码的空间
  • 类的静态成员变量编译时被分配到静态/全局区,因此静态成员变量是属于类的,所有对象共用一份,不计入类的内存空间
  • 静态成员函数和非静态成员函数都是存放在代码区的,是属于类的,类可以直接调用静态成员函数,不可以直接调用非静态成员函数,两者主要的区别是有无this指针,更加详细的解释后面专门写一篇文章
  • 内联函数(声明和定义都要加inline)也是存放在代码区,内联函数在被调用时,编译器会用内联函数的代码替换掉函数,避免了函数跳转和保护现场的开销(实际上到底替不替换还要由编译器决定,即使声明为内联函数也有可能不替换,未声明成内联函数也有可能被编译器替换到调用位置,主要由编译器决定),更详细的介绍后面也会专门写一篇文章

参考文章:

[1] C++成员函数在内存中的存储方式

[2] C++类的实例化对象的大小之sizeof() (该文章有一处错误,“如果是指针,则无论指针指向的是什么数据类型,都占4个字节的存储空间”,在x86目标平台下4Byte,在x64目标平台下8Byte)

如果未特殊说明,以上测试均是在win10 vs2017 64bit编译器下进行的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/498450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

以人工智能的卖点,华为携Mate 10向苹果发起新一轮攻势

华为于10月16日在德国慕尼黑发布了Mate 10系列手机。 Mate 10系列分为Mate 10、Mate 10 Pro和保时捷设计版&#xff0c;都搭载自家的麒麟970处理器。 来源&#xff1a;腾讯科技、PingWest品玩 Mate 10与Mate 10 Pro的主要区别在于屏幕和指纹识别。 Mate 10采用5.9英寸2560 x 14…

英国再推人工智能报告: 四方面发力打造AI强国

来源&#xff1a;腾讯研究院 概要&#xff1a;放眼全球的人工智能领域&#xff0c;美中英是在此领域表现最为突出的三个国家。英国一直是人工智能的研究学术重阵。 导读 放眼全球的人工智能领域&#xff0c;美中英是在此领域表现最为突出的三个国家。英国一直是人工智能的研究学…

手机h5可以用ifreme_折叠照片特效,用手机修图软件就可以实现

前两天有人问下面这种特效是怎么做的&#xff1a;大健看这种折叠照片要发现其中的规律&#xff1a;一是折叠度为90&#xff0c;每一张折叠照片的角度都是&#xff1b;二是对角线平分两张素材的角度为45。所以我们在后期制作这种折叠照片时一定要考虑好这两个条件&#xff0c;不…

“技术崇拜”与“技术恐惧”都会阻碍 AI 创新,“技术节制”才是正道

来源&#xff1a;36氪 概要&#xff1a;我们需要的是一种能够理解我们不断变化的想法的工具&#xff0c;而不是一个一直试图去模仿我们习惯的工具。 我们需要的是一种能够理解我们不断变化的想法的工具&#xff0c;而不是一个一直试图去模仿我们习惯的工具。 随着我们制造的机…

mysql 本地连接_mysql开启远程连接及本地连接

问题描述在本机windows上连接linux服务器上的mysql报错&#xff1a;hostXXX is not allowed to connect to this mysql server。这个错误是由于mysql server没有开启远程连接权限&#xff0c;所以本机连接不上远程的mysql。解决方法开启mysql 远程连接权限一、开启远程连接首先…

人机智能融合--人工智能的未来发展方向

来源&#xff1a;科学网 概要&#xff1a;在经历了三次起伏&#xff08;即上世纪70年代后期对数学定理证明非万能的清醒、90年代后期对专家系统与五代机的失望、2006年深度学习掀起了新一轮的浪潮&#xff09;&#xff0c;人们狂热的希望逐渐踏实了很多&#xff0c;目光和注意力…

mysql先排序再分组筛选_mysql 怎样先排序再分组

权游游牧族&#xff1a;众所周知&#xff01;一句SqL语句不能先排序再分组。所以这里给出几个案例--表结构--create table shop (id int (10) PRIMARY KEY,shop_name varchar (100),item_name varchar (100),price int (10));insert into shop (id, shop_name, item_name,price…

composer 路径_深入学习Composer原理(三)

本系列第三篇文章&#xff0c;一起了解下PSR规范中的PSR4和PSR0规范首先恭喜大家&#xff0c;包括我自己&#xff0c;坚持到了现在。这篇文章之后&#xff0c;Composer的基础原理就清晰明了咯。也就是说&#xff0c;Composer所利用的正是spl_autoload_register()和PSR4规范&…

科普丨深度学习 vs 概率图模型 vs 逻辑学

来源&#xff1a;人工智能爱好者俱乐部 概要&#xff1a;许多早期的人工智能工作都是关注逻辑、自动定理证明和操纵各种符号。John McCarthy于1959年写的那篇开创性论文取名为《常识编程》也是顺势而为。 今天&#xff0c;我们一起来回顾过去50年人工智能(AI)领域形成的三大范式…

如何查看mysql8.0的默认密码_MySQL8.0安装之后查找默认密码

MySQL8.0和MySQL5.7具有众多不同之处,此处不赘述。这里,只简单讲讲在安装过程中遇到的问题之一和解决办法: MySQL8.0安装完成之后的默认密码是多少?如何修改初始密码? 1 启动MySQL服务 启动MySQL服务的命令: shell> sudo service mysqld start Starting mysqld:[ OK ]…

浅析未来大数据的发展趋势

来源&#xff1a;36大数据 概要&#xff1a;随着我国进入大数据时代&#xff0c;很多人对于大数据的发展趋势还处于懵懂的状态&#xff0c;充分提升大数据的应用对于我国各个行业&#xff0c;都会有非常重要和有效的指导性作用。 随着我国进入大数据时代&#xff0c;很多人对于…

mysql update nowait_MySQL 8.0新特性 -- nowait以及skip locked

如果某行记录被事务锁住了&#xff0c;select ... for update、或select ... for share事务对相同的行加锁的时候必须等待&#xff0c;直到产生阻塞的事务释放锁。为了避免等待事务释放锁定的行&#xff0c;nowait和skip locked选项可以被用于select ... for update或select ..…

微软 CEO 纳德拉访谈:人工智能的大方向与未来是什么?

来源&#xff1a;36氪 概要&#xff1a;我们都对科技的发展抱有乐观的态度&#xff0c;我们坚信&#xff0c;人工智能带来的挑战是让我们和社会定义什么是真正的人类。未来将会是一个人工智能强化和增强人类能力的世界&#xff0c;而不是让人类变得更加无用。 人工智能的未来到…

mysql主从是同步还是异步_mysql主从同步异步场景的分析

之所以进行这块内容的研究&#xff0c;主要针对之前遇到的两个未解的疑惑&#xff1a;a&#xff0e; 线上有个系统&#xff0c;半同步状态经常从半同步变成异步&#xff0c;然后又马上恢复为半同步&#xff0c;具体原因未明&#xff0c;虽然之前也猜得八九不离十&#xff0c;但…

不用恐惧AI的高速发展,论击败阿法狗(零)最简单的方法

作者&#xff1a;刘锋 计算机博士&#xff0c;互联网进化论作者 10月19日凌晨&#xff0c;在国际学术期刊《自然》&#xff08;Nature&#xff09;上发表的一篇研究论文中&#xff0c;谷歌下属公司Deepmind报告新版程序AlphaGo Zero&#xff1a;从空白状态学起&#xff0c;在无…

mysql不能设置密码_mysql不能设置密码

你的位置:问答吧-> FreeBSD-> 问题详情mysql不能设置密码ports安装mysql-4.0.15,设置密码时&#xff1a;# mysqladmin -u root password 2568723630mysqladmin: unable to change password; error: Access denied for user: localhost to database mysql也不能添加数据库…

神经网络中的「注意力」是什么?怎么用?

来源&#xff1a;转载自公众号「雷克世界」微信号&#xff1a;ROBO_AI 编译&#xff1a;嗯~阿童木呀、多啦A亮 概要&#xff1a;神经网络中的注意力机制&#xff08;Attention mechanisms&#xff09;&#xff0c;也被称为“神经注意力”或“注意力”&#xff0c;最近吸引了广泛…

redis配置mysql缓存_Redis做mysql的缓存服务器

一redis简介&#xff1a;redis 是一个高性能的 key-value 数据库。 redis 的出现,很大程度补偿了memcached 这类 keyvalue 存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了 Python,Ruby,Erlang,PHP 客户端,使用很方便。Redis 的所有数据都是保存在内存中,然…

2018 年将打响 AI 战争,7 条实战经验帮你战胜恐惧

来源&#xff1a;36氪 概要&#xff1a;不管是对科技巨头还是对创业公司&#xff0c;人工智能可以说是移动互联网时代以来最大的一个机遇。但是&#xff0c;人工智能同时也是让大多数人感到非常困惑的一项新技术&#xff0c;对它的发展现状和未来都非常迷惑。 不管是对科技巨头…

debconf-set-selections mysql_docker 静默安装mysql

1.功能作用在debconf database中插入默认值2.位置/usr/bin/debconf-set-selections3.格式用法debconf-set-selections [-vcu] [file]4.主要参数123-v,--verbose显示运行过程信息-c,--checkonly只检查输入文件的格式-u,--unseen在预置参数时&#xff0c;不设置‘seen‘标识5.应用…