返回首页  设为首页  加入收藏  今天是:
网站首页电脑主板电脑cpu电脑内存电脑硬盘电脑显卡电脑电源显示器电脑配件电脑维修
相关文章
 深入理解 virtual 关键字
 Go 高性能编程技法
 24万买了不亏 NVIDIA最强显卡…
 AMD显卡将支持“黑科技”HYP…
 台式电脑显卡性能天梯图2022…
 3299元!索泰上架新版RTX 30…
 显卡推荐排行榜2020天梯图 台…
 要想电脑主机更省电?这些金…
 300W以下电源怎么选?10款名…
 教你选个好电源 机箱电源频道…
 装机时电源应该选择多少W除此…
 正智总经理老袁教你如何调选…
 移动硬盘什么牌子好 怎么挑选…
 2019硬盘性能排行公布:最强…
 哪个牌子的移动硬盘好 八大移…
 希捷推出Exos Mach2硬盘 最大…
 300多块钱的国产大华C900 1T…
 购买的主板无法使用 华硕却以…
 华硕: 无微不至!华硕主板新…
 相当重口味!独家华硕ROG主板…
 正宗陈教授的主讲 主板维修视…
 Intel 25千兆网卡修复丢包掉…
 【出售】华硕二手笔记本两台…
 裕德里 个人产权 精装
 出售自用台式电脑一套_1
 人人租严选-二手电子产品租赁…
 “因公司经营不善高配9成新电…
 Win10新版发布:CPU内存占用…
 电脑cpu占用过高怎么办 电脑…
 电脑cpu温度过高怎么解决 电…
 perfmonexe占用CPU过高怎么办…
 电脑玩游戏cpu占用过高怎么办…
 拒绝两块大屏的桌面压抑我入…
 2999元!戴尔推出首款便携显…
 双十一好价提前享这几款专业…
 为梦想努力奔跑的人在使用这…
 你见过像平板电脑一样便携的…
 浅谈电脑主板的各个接口的作…
 电脑主板上有哪些接口(笔记本…
 主板上的接口都有哪些 分别是…
 电脑主板接口知识全知道
 简单说明了解电脑主板上的插…
 2022年四六级报名时间是下半…
 内存条要降价?三星、海力士…
 KLEVV科赋CRAS XR5 RGB超频电…
 实测32GB对比16GB:不同内存…
 电脑小知识:装机不求人!10…
 双十一福利活动持续至11月18…
 显卡价格行情(11月15日)矿…
 AMD RX 7000 公版显卡曝光:…
专题栏目
网络
您现在的位置: 电脑评测网 >> 电脑内存 >> 正文
高级搜索
深入理解 virtual 关键字
作者:佚名 文章来源:本站原创 点击数: 更新时间:2022/11/16 12:33:33 | 【字体:

  太牢宴为什么会写这篇文章?主要是因为项目中的代码大量使用了带virtual关键字的类,想通过本文浅谈一下。virtual并没有什么超能力可以化腐朽为神奇,它有其存在的理由,但滥用它是一种非常不可取的错误行为。本文将带你一步一步了解virtual机制,为你揭开virtual的神秘面纱。

  假设我们正在进行一个公共图形化库的设计实现,其中涉及2d和3d坐标点的打印,设计出Point2d和Point3d的实现如下:

  完美,一切都符合预期。既然如此,我们为什么需要virtual?让我们提个新需求:封装一个坐标点打印接口,输入是坐标点实例,输出是坐标点的值。很快,我们实现了代码:

  问题来了,当我们传入3d坐标点实例时,我们的期望是打印3d坐标点的值,而实际只能打印2d坐标点的值。现在的程序分不清坐标点是2d还是3d,为了让程序变得更聪明,需要对症下药,而virtual正是该症的药方。只需要更新Point2d接口print的声明即可:

  干的漂亮,一切又恢复完美如初。在c++继承关系中实现多态的威力,正是需要virtual的地方。那么它的神奇魔力究竟从何而来呢?一切要从类数据成员内存布局说起。

  在c++对象模型中,非静态数据成员被配置于每一个类对象之内,静态数据成员则被存放在类对象之外。静态和非静态函数成员也被存放在类对象之外。大多数编译器对类的内存布局方式是按成员的声明顺序依次排列,本文的所有例子都是在mac环境下,使用x86_64-apple-darwin21.6.0/clang-1300.0.29.3编译,非virtual版本的Point2d内存布局:

  内存布局需要我们注意的是编译器对内存的对齐方式,内存对齐一般分两步:其一是类成员先按自身大小对齐,其二是类按最大成员大小对齐。我们在安排类成员的时候,应该遵循成员从大到小的顺序声明,这样可以避免不必要的内存填充,节省内存占用。

  在c++的继承模型中,一个子类的内存大小,是其基类的数据成员加上其自己的数据成员大小的总和。大多数编译器对子类的内存布局是先安排基类的数据成员,然后是本身的数据成员。非virtual版本的Point3d的内存布局:

  当Point2d声明了virtual函数后,对类对象产生了两点重大影响:一是类将产生一系列指向virtual functions的指针,放在表格之中,这个表格被称之为virtual table(vtbl)。二是类实例都被安插一个指针指向相关的virtual table,通常这个指针被称为vptr。为了示例需要,我们重新设计Point2d和Point3d实现:

  大多数编译器把vptr安插在类实例的开始处,现在我们来看看virtual版本的Point2d和Point3d的内存布局:

  另一个有趣的地方是虚函数指针的定义,有没有让你联想到什么?你没想错,正是c++类this指针的存在:类成员函数里的this指针,其实是编译器将类实例的地址以第一个参数的形式传递进去的。和其他任何参数一样,this指针没有任何特别之处!

  前文中我们都没设计析构函数,是因为要在这里单独讲解。让我们重新设计下继承体系,加入Point类:

  可以看到,非virtual析构函数版本,决定继承体系中析构函数链调用的因素是指针的声明类型:析构函数的调用从声明指针类型的类开始,依次调用其父类析构函数。现在我们把Point的析构函数声明为virtual,来看下同样调用的结果:

  virtual析构函数版本,决定继承体系中析构函数链调用的因素是指针的实际类型:析构函数的调用从指针指向的实际类型的类开始,依次调用其父类析构函数。

  我看过项目中很多模块的代码,大量的类不管三七二十一都把析构函数声明为virtual。关键是这样的类既不是设计用于基类继承,也不是设计要使用多态能力,简直让人哭笑不得。现在你能理解为啥滥用virtual是不对的吗?因为在非必需的情况下,引入virtual实在不是一个明智的选择,它会带来两个明显的副作用:其一是每个类额外增加一个指针大小的内存占用,其二是函数调用多一层间接性。这两个特性会带来内存与性能的双重消耗。

  其中内存的消耗是固定的一个指针大小,似乎看起来不起眼,但在类没有成员或者成员很少的情况下,就会带来100%以上的内存膨胀。性能的消耗则更加隐蔽,virtual会带来构造函数的强制合成,这点可能出乎很多人的意料。为何呢?因为虚表指针需要被安插妥当,因此编译器需要在类构造的时候做好这项工作。如果我们再声明一个虚析构函数,那将再引入一个非必要的合成函数,造成性能的双杀。让我们来瞧瞧这样做的后果:

  可以看到VPoint2d自动合成了构造和析构函数,以及typeinfo信息。作为对比Point2d则没有合成任何函数,我们看下两者的执行效率:在作者mac机器上,三次demo执行的结果取中间值是Point2d:12819,VPoint2d:21833,VPoint2d性能耗时增加了9014次clock,增幅达70.32%。

  因此,一定不要随意引入virtual,一定不要随意引入virtual,一定不要随意引入virtual,除非你线.在继承中使用多态能力的时候,需要使用virtual functions机制;

  任何其他时候,virtual并没有其他你想要的任何魔力且会有反噬作用。其实还有一种情况需要virtual,就是virtual base class,由于这种情况太过于复杂,建议任何时候都不要去尝试它(可能需要另外一篇长文来解释为何不建议使用,本文暂且不表)。

  关于virtual的讲解至此结束,不多不少,不知对你来说是否够用。希望本文对你了解和使用virtual可以起到帮助作用。c++复杂且庞大,很多特性都有它使用的场景和限制,我们只有深入了解其背后的机制,才能做到宠辱不惊,看庭前花开花落;去留无意,望天上云卷云舒;。

  最后,本文参考了《深度探索c++对象模型》一书。毋须多言,我觉得这是一本关于c++的必读书籍。希望大家有空都可以看看,一定会让你开卷有益、相见恨晚。

  郭德纲:我北京三套四合院价值2.6亿,说给就给,就等孟非个准线斤了,还敢穿挂脖礼服,看上去就像个彪形大汉!

  张学友拍摄《东成西就》期间被刘嘉玲张国荣叫去打麻将, 发现居然有3个是出老千

  多家劳务中介:连花清瘟生产商以岭药业急招大量短期工 公司官网亦发布招聘信息

  乌克兰希望国际援助中50%是赠与形式;欧盟已向乌克兰提供了价值至少80亿欧元的军事装备;美国已经承诺向乌克兰提供超过193亿美元的军事援助

  苹果 iPhone 14 Pro 系列 AOD 息屏显示现已支持禁用壁纸或通知

电脑内存录入:admin    责任编辑:admin 
  • 上一个电脑内存:

  • 下一个电脑内存: 没有了
  •  
     栏目文章
    普通电脑内存 深入理解 virtual 关键字 (11-16)
    普通电脑内存 Go 高性能编程技法 (11-16)
    普通电脑内存 2022年四六级报名时间是下半年吗 四六级报名网… (11-16)
    普通电脑内存 内存条要降价?三星、海力士等厂商不答应 (11-16)
    普通电脑内存 KLEVV科赋CRAS XR5 RGB超频电竞内存条体验评测 (11-16)
    普通电脑内存 实测32GB对比16GB:不同内存下的体验差距你感… (11-16)
    普通电脑内存 电脑小知识:装机不求人!10 分钟电脑配置挑选… (11-16)
    普通电脑内存 电脑运行内存4g和6g的区别 (11-15)
    普通电脑内存 内存和SSD疯狂降价清库存:好日子快到头了 (11-15)
    普通电脑内存 DRAM(内存)板块11月14日涨102%兆易创新领涨… (11-15)
    普通电脑内存 内存 - OFweek电子工程网 (11-15)
    普通电脑内存 科技笑谈——500G内存的电脑是什么鬼 (11-15)
    普通电脑内存 英语双语报官网 (英语双语报官网答案2022) (11-15)
    普通电脑内存 从顶级科技企业到折戟科创板:联想欠倪光南院… (11-15)
    普通电脑内存 儿童动画学英语颜色(幼儿学颜色英语) (11-15)
    普通电脑内存 电脑提示svchost占用内存过高怎么办 (11-15)
    普通电脑内存 干得漂亮!谷歌将减少Chrome在Win10内存占用 (11-15)
    普通电脑内存 太笨了2w月薪工程师连电脑蓝屏都修不好!幻龙… (10-21)
    普通电脑内存 「内存」这个名字误导性太强为什么没有一个更… (10-21)
    普通电脑内存 计算机常用电脑 英语 缩写学习伍娇近况夏沫之… (10-21)