constructor可能内带大量的隐藏码,因为编译器会扩充每一个constructor,扩充程度视class的继承体系而定。一般而言编译器所做的扩充操作大约如下: 记录在member initialization list中的data members初始化操作会被放进constructor的函数本身,并以members的声明顺序为顺序。 如果有一个member并没有出现在member initialization之中,但它有一个default constructor,那么该default constructor必须被调用。 在2之前,如果class object有virtual table pointer(s),它(们)被设定初值,指向适当的virtual table(s)。 在3之前,所有上一层的base class constructors必须被调用,以base class的声明顺序为顺序: 如果base class被列于member initialization list中,那么任何明确指定的参数都应该传递过去。 如果base class没有被列于member initialization list中,而它有default constructor,那么就调用之。 如果base class是多重继承下的第二或后继的base class,那么this指针必须有所调整。 在4之前,所有virtual base class constructors必须被调用,从左到右,从最深到最浅: 如果class被列于member initialization list中,那么如果有任何明确指定的参数,都应该传递过去。若没有列于list之中,而class中一个default constructor,也应该调用之。 此外,class中的每一个virtual base … Continue reading →
一、成员函数的调用方式 1.Nonstatic member functions C++的设计准则之一就是:nonstatic member function 至少必须和一般的nonmember function有相同的效率。而实际上,编译器内部会将“member函数实体”转换为对等的“nonmember函数实体”。其转化步骤大致如下: 改写函数的signature(函数名称+参数数目+参数类型)以安插一个额外的参数到member function中,用以提供一个存取管道,使class object得以调用该函数。该额外参数被称为this指针。 将每一个“对nonstatic data member”的存取操作“改为经由this指针来存取”。 对member function重新写成一个外部函数。对函数名称进行“mangling”处理,使它在程序中成为独一无二的语汇(比如将参数 类型和返回值类型也编码进来)。
本来是想将这里弄成纯技术博客的,想着想着也太单调了,还是配合一下吐槽会比较有美感。 回想起来,前两年日子都是过得比较有压力,当然也有伤感啦。现在听着的歌是《答应不爱你》,感觉还挺好听的。工作这半年多以后,最深的感触就是工作环境比较轻松,大家都很nice,我很喜欢这种气氛,在这里有很大的学习空间,还有的是我经常能够穿拖鞋上班,虽然HR跟我说过上班不要穿人字拖,可是可是…… 其实我很怀念那段封闭开发的日子,因为封闭开发感觉很清静,没有在大楼那么吵杂,这样使人能够专心工作。而且项目进度紧,我觉得反而提高自己的专注力,现在工作没有那么紧,虽然可以多点时间学习,但是感觉也颇为有点懒,思维也没有那么活跃。但也不想每天都搞到12点,这样我就没有时间看书了。
一、Data Member的存取 static data members,会被编译器提出于class之外,并被视为一个global变量(但只在class生命范围之内可见)。每一个member的存取许可(private, protected, public),以及与class的关联,并不会导致任何空间上或执行时间上的额外负担——不论是在个别的class objects或是在static data member本身。每一个static data member只有一个实体,存放在程序的data segment之中。 nonstatic data members直接存放在每一个class object之中。每一个nonstatic data member的偏移量(offset)在编译时期即可获知,甚至如果member属于一个base class subobject(派生自单一或多重继承串链)也是一样。因此,存取一个nonstatic data member,其效率和存取一个C struct member或一个nonderived class的member是一样的。 但是使用继承和指针还是会带一些差异的,如下代码: // Point3d是一个derived class 其定义就忽略哈 Point3d origin, *pt = &origin; origin.x = 0.0; pt->x … Continue reading →
一、缓存协商 在使用缓存的时候,我们不但需要在Web服务器上使用缓存,同时也尽可能地让Web站点的内容缓存在用户的浏览器中,特别是一些长期不会出现更改的静态文件,这样将在一定程度减少了服务器的计算机开销,而且也避免了有些内容由于不必要的传输而带来的带宽浪费。 通过IE的选项打开IE的缓存目录,可以看到: 其中有Internet地址,截止期限( Expires ),上次修改时间( Last-Modified )等等文件信息。 对于Firefox浏览器,它存储缓存文件的方式有所不同。并不像IE那样将每个文件独立存储,而是采用二进制文件的方式来存储和管理缓存文件。