前言 在C++对象模型的那些事儿之四:拷贝构造函数中提到如果将一个对象作为函数参数或者返回值的时候,会调用拷贝构造函数,编译器是如何处理这些步骤,又会对其做哪些优化呢?本篇博客就为他家介绍一个编译器的优化操作:NRV,以及关于初始化列表的一些容易踩的"坑"! NRV NRV是named Return Value的缩写,翻译过来就是具名返回值优化,这个优化到底在编译层干了些什么事,我们先来看个例子: class Animal{ public: Animal(){ cout<<…
前言 对于一个没有实例化的空类,编译器不会给它默认生成任何函数,当实例化一个空类后,编译器会根据需要生成相应的函数.这类函数包括一下几个: 构造函数 拷贝构造函数 析构函数 赋值运算符 在上一篇博文C++对象模型的那些事儿之三:默认构造函数中讲到,编译器在需要的时候会合成一个空构造函数.本篇博文中就重点来介绍一下第二主角:拷贝构造函数. 引子 正如Linus Torvalds说的一句话:"Talk is cheap,Show me the code".在程序员的世界里,讲再多都不如直接…
前言 继前两篇总结了C++对象模型及其内存布局后,我们继续来探索一下C++对象的默认构造函数.对于C++的初学者来说,有如下两个误解: 任何class如果没有定义default constructor,就会被合成出来 编译器合成出来的default constructor会显示设定"class内每一个data member的默认值" 如果读者对这两句话理解颇深,了解里面的陷阱,那么可以不必阅读下去:倘若你有一点点疑惑,那非常好,跟着我一起继续下去! 无用(trivial)的构造函数 一…
前言 上一篇博客C++对象模型的那些事儿之一为大家讲解了C++对象模型的一些基本知识,可是C++的继承,多态这些特性如何体现在对象模型上呢?单继承.多重继承和虚继承后内存布局上又有哪些变化呢?多态真正的底层又是如何实现呢?本篇博客就带大家全面理解一下C++对象模型,从而理解上述疑惑. 引例 还是以上篇博客的Animal类说起,假设我们有一个Dog类,它继承了Animal类.程序如下: class Animal{ public: char name[10];//动物名字 int weight;//…
前言 很早以前就听人推荐了<深入理解C++对象模型>这本书,从年初买来到现在也只是偶尔翻了翻,总觉得晦涩难懂,放在实验室上吃灰吃了好久.近期由于找工作对C++的知识做了一个全面系统的学习,基础相对扎实了不少,于是,又重新拿起这本书,突然觉得里面的知识也不那么难懂,而且越看越有意思,不愧是C++高阶教程啊!耐着性子,抓着头皮花了两个多月,总算对其中的知识有了一些理解,部分章节反反复复的看,每次都有新的收获.所谓好记性不如烂笔头,本系列博文就对我所学到的知识和我所遇到的困惑做一个整理. 引例 我以…
前言 C++的成员函数分为静态函数.非静态函数和虚函数三种,在本系列文章中,多处提到static和non-static不影响对象占用的内存,而虚函数需要引入虚指针,所以需要调整对象的内存布局.既然已经解决了数据,函数等在内存中的布局问题,下一个需要考虑的就是如何调用,上述提到的三种函数的调用机制都不一样,其间的差异正是本篇博客需要讨论的. 非静态成员函数 C++的设计准则之一就是:非静态成员函数至少必须和一般的非成员函数有相同的效率.要达到这一点,成员函数的成员属性不会给其带来额外的负担.考虑以…
1 前言 在C++中类的数据成员有两种:static和nonstatic.类的函数成员由三种:static,nonstatic和virtual. 上篇我们尽量说一些宏观上的东西,数据成员与函数成员在类中的布局将在微观篇中具体讨论. 每当我们声明一个类.定义一个对象.调用一个函数.....的时候,不知道你有没有一些疑惑--编译器私底下都干了些什么?普通函数.成员函数都是怎么调用的?static成员又是个什么玩意. 假设你对这些东西也感兴趣,那么好,我们一起将class的底层翻个底朝天.修炼好底层的…
在c++中,有2种class data member:static和nostatic,以及3钟class member function:static,nostatic和virtual.已知下面这个class Point声明: class Point { public: Point(float xval); virtual ~Point(); float x() const; static int PointCount(); protected: virtual ostream& print(o…
C++对象模型中加入多继承 从单继承可以知道,派生类中只是扩充了基类的虚函数表.如果是多继承的话,又是如何扩充的? 1)        每个基类都有自己的虚表. 2)        子类的成员函数被放到了第一个基类的表中. 3)        内存布局中,其父类布局依次按声明顺序排列. 4)        每个基类的虚表中的print()函数都被overwrite成了子类的print ().这样做就是为了解决不同的基类类型的指针指向同一个子类实例,而能够调用到实际的函数. 上面3个类,Deriv…
DOM是前端编程中一个非常重要的部分,我们在动态修改页面的样式.内容.添加页面动画以及为页面元素绑定事件时,本质都是在操作DOM.DOM并不是JS语言的一个部分,我们通过JAVA.PHP等语言抓取网页内容时需要对网页进行解析并拿到我们感兴趣的那部分内容,这时其实也是在操作DOM.当然在前端领域,我们肯定还是通过JS来操作DOM,而DOM也是伴随JS的出现而诞生的,随着前端的不断发展,DOM标准也在不断演进,每个新的版本都为DOM进行了一定程度的扩展.本文主要总结DOM1级中的核心内容.   1.…