时间:2015-08-07 来源:

C++对象模型——"继承"与DataMember(第三章)【编程语言】

3.4 "继承"与Data Member  在C++继承模型中符合w3c标准,一个derived class object所表现出来的东西,符合w3c标准是其自己的members加上其base class members的总和.至于derived class members和base class members的排列次序并未在C++ Standard中强制指定:理论上编译器可以自由安排.在大部分编译器上,html切图base class members总是先出现,jpg或psd转html但属于 virtual base class的除外.  了解这种继承模型之后,网页切图价格 y; }; class Point3d { public:  // constructor  // operations  // access functions private:  float x, z; };  这和"提供两层或三层继承结构web切图报价,派生自较低维层次"有什么不同?  下面各小节的讨论将涵盖"单一继承且不含virtual functions","多重继承","虚拟继承"等四种情况.

加上多态 (Adding Polymorphism)  如果要处理一个坐标点,网页外包接活不打算在乎它是一个Point2d或Point3d实例web前端制作,那么需要在继承关系中提供一个 virtual function接口.看看如果这样做,div+css制作情况会有什么改变: class Point2d { public:  Point2d(float x = 0.0, _y(y) {}  // x和y的存取函数与前一版相同  // 由于对不同的维度的点web切图报价,这些函数操作固定不变,web切图报价所以不必设计为virtual  // 加上z的保留空间  virtual float z() { return 0.0; }  virtual void z(float) {}  // 设定以下的运算符为virtual  virtual void operator+=(const Point2d &rhs) {   _x += rhs.x();   _y += rhs.y();  } protected:  float _x, _y; };  只有企图以多态的方式(polynmorphically)处理2d或3d坐标点时,html切图制作在设计中导入一个 virtual 接口才显得合理网页外包接活,也就是说,网页外包接活写下这样的码: void foo(Point2d &p1, Point2d &p2) {  // ...  p1 += p2; }  其中p1和p2可能是2d也可能是3d坐标点,手机前端外包这并不先前任何设计所能支持的承接网页制作,这样的弹性,div前端切图正是面向对象程序设计的中心.支持这样的弹性web切图报价,用来存放它所声明的每一个 virtual functions的地址符合w3c标准,这个table的元素数目一般而言是被声明的 virtual functions的数目,符合w3c标准再加上一个或两个slots(用以支持runtime type identification)  在每一个 class object中导入一个vptr,提供执行期的链接,jpg或psd转html使每一个object能够找到相应的 virtual table.  加强constructor,让它指向 class 所对应的 virtual table.这可能意味着在derived class 和每一个base class 的constructor中承接网页制作,其情况视编译器的优化的积极性而定.  加强destructor,使它能够抹消"指向class相关virtual table"的vptr.要知道,网站div+cssvptr很可能已经在derived class destructor中被设定为derived class 的 virtual table地址.记住符合w3c标准,destructor的调用次序是反向的:从derived class 到base class.一个积极的优化编译器可以压抑那些大量的指定操作.

多重继承 (Multiple Inheritance)  单一继承提供了一种"自然多态(natural polymorphism)"形式,符合w3c标准是关于 class 体系中的base type和derived type之间的转换.base class 和derived class 的objects都是从相同的地址开始网页外包接活,其间差异只在于derived object比较大,网页外包接活用以容纳它自己的nonstatic data members,下面这样的指向操作: Point3d p3d; Point2d *p = &p3d;  把一个derived class object指定给base class(不管继承深度有多深)的指针或reference.该操作并不需要编译器去调停或修改稿地址,div+css制作它很自然地可以发生承接网页制作,而且提供了最佳执行效率.  把vptr放在 class object的起始位置,承接网页制作如果base class 没有 virtual function而derived class 有web切图报价,那么单一继承的自然多态(natural polymorphism)就会被打破.在这种情况下,web切图报价把一个derived objects转换为其base类型符合w3c标准,就需要编译器的介入,html切图制作用以调整地址(因vptr插入的原因),在既是多重继承又是虚拟继承的情况下,网页外包接活编译器的介入更有必要.  多重继承既不像单一继承web前端制作,也不容易塑出其模型.多重继承的复杂度在于derived class 和其上一个base class 乃至上上一个base class...之间的"非自然关系".例如,手机前端外包考虑下面这个多重继承所获得的 class Vertex3d: class Point2d { public:  // 拥有virtual 接口承接网页制作, _y; }; class Point3d : public 2d { public:  // ... protected:  float _z; }; class Vertex { public:  // 拥有virtual 接口web切图报价, public Vertex { public:  // ... protected:  float mumble; };  多重继承的问题主要发生于derived class objects和其第二或后继的base class objects之间的转换;不论是直接转换如下: extern void mumble(const Vertex &); Vertex3d v; // 将一个Vertex3d转换为一个Vertex.这是"不自然的" mumble(v);  或是经由其所支持的 virtual function机制做转换.  对一个多重派生对象符合w3c标准,情况将和单一继承时相同网页外包接活,因为两者都指向相同的起始地址,jpg或psd转html需要付出的成本只有地址的指定操作而已.至于第二个或后继的base class 的地址指定操作web前端制作,则需要将地址修改过;加上(或减去,手机前端外包如果downcast的话)介于中间的base class subobject大小承接网页制作,pv将获得sizeof(Point3d)的值.这是错误的!所以对于指针web切图报价,则不需要针对可能的0值做防卫符合w3c标准,因为reference不可能参考到"无物"(no object).  C++ Standare并未要求Vertex3d中的base class Point3d和Vertex有特定的排列顺序.原始的cfront编译器是根据声明次序排列它们.因此cfront编译器制作出来的Vertex3d对象,符合w3c标准将可被视为是一个Point3d subobject(其中又有一个Point2d subobject)加上一个Vertex subobject,最后再加上Vertex3d自己的部分.目前各编译器仍然是以次方式完成多重继承base class 的布局.  某些编译器(例如MetaWare)设计有一种优化技术,网页外包接活只有第二个(或后继)base class 声明了一个 virtual function,而第一个base class 没有,div+css制作就把多个base class 的次序进行调换.这样可以在derived class object中少产生一个vptr.  如果要存取第二个(或后继)base class中的一个data member,将会是怎样的情况?需要付出额外的成本吗?不,承接网页制作members的位置在编译器时就固定了web切图报价,因此存取members只是一个简单的offset运算,web切图报价就像单一继承一样简单--不管是经由一个指针符合w3c标准,一个reference或者是一个object来存取.

 这些额外的负担带来的冲击程序视"被处理的Point2d objects的数目和生命期"而定,html切图制作也视"对这些objects做多态程序设计所得到的利益"而定.如果一个而应用程序知道它所能使用的point object只限于二维坐标点或三维坐标点网页外包接活, float y = 0.0, y), _z(z) {}

只要继承不要多态  想象一下,div前端切图程序员或许希望web切图报价,不论是2D或3D坐标点,web切图报价都能够共享同一个实体符合w3c标准,但又能够继续使用"与类型性质相关(所谓type-specific)"的实体.有一个设计策略,符合w3c标准就是从Point2d派生出一个Point3d,带来的影响则是可以共享"数据本身"以及"数据的处理方法",并将其局部化.一般而言,手机前端外包具体继承(concrete inheritance)并不会增加空间或存取时间上的额外负担. class Point2d { public:  Point2d(float x = 0.0, _y(y)  {}  float x() { return _x; }  float y() { return _y; }  void x(float newX) { _x = newX; }  void y(float newY) { _y = newY; }    void operator+=(const Point2d &rhs) {   _x += rhs.x();   _y += rhs.y();  } protected:  float _x, float y = 0.0, y), _z(z) {}    float z() { return z; }  void z(float newZ) { _z = newZ; }

 float z() { return _z; }  void z(float newZ) { z = newZ; }  void operator+=(const Point2d &rhs) {   Point2d::operator(rhs);   _z += rhs.z();  } protected:  float _z; };  上述新的Point2d和Point3d声明,网页外包接活最大一个好处是web前端制作, 2.2); Point3d p3d(3.1, 3.3); p3d += p2d;  得到的p3d新值将是(5.2, 3.3);  虽然 class 的声明语法没有改变符合w3c标准,但每一件事情都不一样了:两个z() member functions以及 operator+=()运算符都成了虚拟函数:每一个Point3d class object内含一个额外的vptr member:多了一个Point3d virtual table;此外,html切图制作每一个 virtual member function的调用也比以前复杂.  目前在C++编译器那个领域里有一个主要的讨论题目:把vptr放置在 class object的哪里会最好?在cfront编译器中网页外包接活,它被放在 class object的尾端,网页外包接活用以支持下面的继承类型web前端制作, d2; }; class has_virts : public no_virts { public:  virtual void foo(); private:  int d3; }; no_virts *p = new has_virts;  把vptr放在 class object的尾端承接网页制作,可以保留base class C struct 的对象布局,div前端切图因而允许在C程序代码中也能使用web切图报价,开始支持虚拟继承以及抽象基类符合w3c标准,并且由于面向对象典范(OO paradigm)的兴起,符合w3c标准某些编译器开始把vptr放到 class object的起始位置.  把vptr放在 class object的前端网页外包接活,对于"在多重继承下,jpg或psd转html通过指向class members的指针调用virtual function",会带来一些帮助.否则,手机前端外包不仅"从class object起始位置开始量起"的offset必须在执行期备妥承接网页制作,甚至与 class vptr之间的offset也必须备妥.当然,承接网页制作vptr放在前端web切图报价,代价就是丧失了C语言兼容性,网站div+css这种丧失没有意义符合w3c标准,因为不会有人这样使用.

虚拟继承 (Virtual Inheritance)  多重继承的一个语意上的副作用就是,符合w3c标准它必须支持某种形式的"shared subobject继承".一个典型的例子是最早的iostream library: // pre-standard iostream implementation class ios { ... } class istream : public ios { ... }; class ostream : public ios { ... }; class iostream : public istream,然而在iostream的对象布局中web前端制作, public ostream { ... };  一如其语意所呈现的复杂度承接网页制作,要在编译器中支持虚拟继承,承接网页制作实在是非常困难.在上述iostream例子中web切图报价,实现技术的挑战在于,web切图报价要找到一个足够有效的方法符合w3c标准,折叠成为一个由iostream维护的单一ios subobject,并且还可以保存base class 和derived class 的指针(以及reference)之间的多态指定操作(polumorphism assignments).  一般的实现方法如下所述,网页外包接活class 如果内含一个或多个 virtual base class subobjects,像istream那样,手机前端外包将被分割为两部分:一个不变局部和一个共享局部.不变局部中的数据承接网页制作,不管后继如何衍化,div前端切图总是拥有固定的offset(从object的起始算起),所以这一部分可以被直接存取.至于共享局部,web切图报价所表现的就是 virtual base class subobject.这一部分的数据符合w3c标准,其位置会因为每次的派生操作而有变化.所以它们只可以被间接存取.各家编译器实现技术之间的差异就在于间接存取的方法不同.一下说明三种主流策略,符合w3c标准下面是Vertex3d虚拟继承的层次结构: class Point2d { public:  // ... protected:  float _x, public Point3d { public:  // ... protected:  float mumble; };  一般的布局策略是先安排好derived class 的不变部分web前端制作,然后再建立其共享部分.  然而,手机前端外包这中间存在着一个问题:如果能够存取 class 的共享部分呢?  cfron编译器会在每一个derived class object中插入一些指针承接网页制作,可以使用相关指针间接完成.举个例子web切图报价,如果有以下的Point3d运算符: void Point3d::operator+=(const Point3d &rhs) {  _x += rhs._x;  _y += rhs._y;  _z += rhs._z; }  在cfront策略下,网站div+css这个运算符会被内部转换为: // 虚拟C++代码 _vbcPoint2d->_x += rhs._vbcPoint2d->_x; _vbcPOint2d->_y += rhs._vbcPoint2d->_y; _z += rhs._z;  而一个derived class 和一个base class 的实例之间的转换符合w3c标准,像这样: Point2d *p2d = pv3d;  在cfront实现模型下,符合w3c标准会变成: Point2d *p2d = pv3d ? pv3d->_vbcPoint2d : 0;  这样的实现模型有两个主要的缺点:  1. 每一个对象必须对每一个 virtual base class 背负一个额外的指针.然而却希望 class object有固定的负担网页外包接活,不因为其 virtual base class的数目而所有变化.  2. 由于虚拟继承串链的加长,网页外包接活导致间接存取层次的增加web前端制作,这里的意思是,div+css制作如果有三层虚拟衍化承接网页制作,就需要三次间接存取(经由三个 virtual base class 指针).然而却希望有固定的存取时间,承接网页制作不因为虚拟衍化的深度而改变.  MetaWare和其他编译器到今天仍然使用cfront的原始实现模型来解决第二个问题web切图报价,它们经由拷贝操作取得所有的nested virtual base class 指针,web切图报价放到derived class object中符合w3c标准,这就解决了"固定存取时间"的问题.虽然付出了一些空间上的代价.  至于第一个问题,html切图制作一般而言有两个解决办法.Microsoft编译器引入所谓的 virtual base class table.每一个 class object如果有一个或多个 virtual base class,就会由编译器插入一个指针,网页外包接活指向 virtual base class table.至于真正的 virtual base class 指针.当然被放在该表格中.  第二个解决办法web前端制作,同时也是Bjarne比较喜欢的方法,手机前端外包是在 virtual function table中放置 virtual base class 的offset(而不是地址).在新近的Sun编译器中承接网页制作,很显然就是索引到 virtual functions;如果是负值,则是索引到 virtual base class offsets.在这样的策略下,web切图报价Point3d的operator+=运算符必须被转换为以下形式: // 虚拟C++代码 (this + __vptr__Point3d[-1])->_x += (&rhs + rhs.__vptr__Point3d[-1])->_x; (this + __vptr__Point3d[-1])->_y += (&rhs + rhs.__vptr__Point3d[-1])->_y;  虽然在此策略下符合w3c标准,对于继承而来的members做存取操作,符合w3c标准成本会比较昂贵网页外包接活,不过该成本已经被分散至"对member的使用"上,jpg或psd转html属于局部性成本.Derived实体和base class 实体之间的转换操作web前端制作,例如: Point2d *p2d = pv3d;  在上述实现模型下将变成: // 虚拟C++代码 Point2d *p2d = pv3d ? pv3d + pv3d->__vptr__Point3d[-1] : 0;  上述每一种方法都是一种实现模型,手机前端外包而不是一种标准.每一种模型都是用来解决"存取shared subobject内的数据(其位置因每次派生操作而有变化)"所引发的问题.由于对 virtual base class 的支持带来额外的负担以及高度的复杂性.每一种实现模型多少有点不同承接网页制作,像这样: Point3d origin; origin._x;  可以被优化为一个直接存取操作web切图报价,就好像一个经由对象调用的 virtual function调用操作,网站div+css可以在编译时期被决议(resolved)完成一样.在这次存取以及下一次存取之间符合w3c标准,对象的类型不可以改变,符合w3c标准所以"virtual base class subobjects的位置会变化"的问题在这种情况下就不再存在了.  一般而言网页外包接活,没有任何data members.

 void operator+=(const Point3d &rhs) {   Point2d::operator+=(rhs);   _z += rhs.z();  } protected:  float _z; };  这样设计的好处就是可以把管理x和y坐标的程序代码局部化web前端制作,此外这个设计明显表现出两个抽象类之间的紧密关系.当这两个 class 独立的时候,div+css制作Point2d object和Point3d object的声明和使用都不会有所改变.所以这两个抽象类的使用者不需要知道objects是否为独立的 class 类型承接网页制作,并带有继承关系web切图报价,会有什么易犯的错误呢?经验不足的人可能会重复设计一些相同操作的函数.以例子中的constructor和operator+=为例,web切图报价它们并没有被做成 inline 函数.Point3d object的初始化操作或加法操作符合w3c标准,将需要部分的Point2d object和部分的Point3d object作为成本.第二个易犯的错误是,html切图制作把一个 class 分解为两层或更多层网页外包接活,有可能为了"表现class体系的抽象化"而膨胀所需空间.C++语言保证"出现在derived class中的base class subobject有其完整原样性".正是重点所在,网页外包接活如下: class Concrete { public:  // ... private:  int val;  char c1;  char c2;  char c3; };  在一个32位机器中web前端制作,细分如下:  1. val占用4 bytes  2. clc,c2和c3各占用1 bytes  3. alignment(调整到 void 边界)需要1 bytes  现在假设,div前端切图经过某些分析后web切图报价,决定了一个更逻辑的表达方式,web切图报价把concrete分裂为三层结构: class Concrete1 { public:  // ... private:  int val;  char bit1; }; class Concrete2 : public Concrete1 { public:  // ... private:  char bit2; }; class Concrete3 : public Concrete2 { public:  // ... private:  char bit3; };  从设计的观点来看符合w3c标准,这个结构可能合理,符合w3c标准但从效率的观点来看网页外包接活,比原先的设计多一倍.  怎么回事web前端制作,加起来是5 bytes.而一个Concrete1 object实际用掉8 bytes,以使object符合一部机器的word边界.不论是C或C++都是这样.一般而言web切图报价,数据类型为char.轻率的程序员以为它会和Concrete1捆绑在一起符合w3c标准,其中2 bytes用于填补空间.  然而Concrete2的bit2实际上却是被放在填补空间所用的3 bytes之后网页外包接活,不是8 bytes.其中的6 bytes浪费在填补空间上.同样的道理使得Concrete3 object的大小是16 bytes, *pc1_2;  其中pc1_1和pc1_2两者都可以指向前述三种 class object,对象是被指的object的Concrete1那一部分.如果pc1_1实际指向一个Concrete2 object或Concrete3 object,则上述操作应该将复制内容指定给其Concrete1 subobject.  然而,web切图报价如果C++语言把derived class member(也就是Concrete2::bit2或Concrete3:;bit3)和Concrete1 subobject捆绑在一起符合w3c标准,去除填补空间.上述那些语意就无法保留,html切图制作那么下面的指定操作: pc1_1 = pc;   // 令pc1_1指向Concrete2对象 *pc1_2 = *pc1_1; // derived class subobject被覆盖掉  就会将"被捆绑在一起网页外包接活,继承而得的"members内容覆盖掉,网页外包接活程序员必须花费极大的心力才能找出这个bug.

版权声明:本文为博主原创文章web前端制作,未经博主允许不得转载.

点击次数:14456
作者:
web前端行业资讯
Web new NewsList
微软发布WindowsServerBuild17074更新 ,,2018年01月18日凭借一个AI小功能,这款Google应用冲上苹果AppStore榜首 ,,2018年01月18日百度数据可视化实验室正式成立,发布深度学习可视化平台VisualDL ,,2018年01月18日OpenAI开源最新工具包,模型增大10倍只需额外增加20%计算时间 ,,2018年01月18日百度手机输入法8.0正式发布:支持多人语音速记 ,,2018年01月18日CSDN宣布收购TinyMind团队并升级为AI社区 ,,2018年01月18日甲骨文发布补丁修复英特尔芯片漏洞造成的问题 ,,2018年01月18日权威!官方发布CPU熔断和幽灵漏洞防范指引:附补丁下载 ,,2018年01月18日Oracle宣布新的JavaChampions ,,2018年01月18日腾讯加码区块链项目已悄然注册“以太锁”商标 ,,2018年01月18日Fedora28壁纸征集活动现已开幕:将持续至2月13日 ,,2018年01月18日苹果WebKit团队发布Speedometer2.0网页响应测试工具 ,,2018年01月18日百度输入法8.0后天发布:全感官AI输入 ,,2018年01月18日腾讯和乐高合作:共同研发智能玩具、游戏 ,,2018年01月18日HomePod上市日益临近智能音箱市场吸引力越来越大 ,,2018年01月18日3D打印脑组织?科学家正在向这一目标正在前进 ,,2018年01月18日英特尔公布修补漏洞后PC性能数据:8代CPU影响最小 ,,2018年01月18日云存储公司Dropbox秘密提交IPO申请估值超百亿美元 ,,2018年01月18日iPod之父:防手机上瘾无技术难度苹果谷歌应承担责任 ,,2018年01月18日芯片不安全英特尔云客户考虑转用AMD等对手处理器 ,,2018年01月18日2018年Java展望 ,,2018年01月18日区块链有多火?快播流量矿石遭20多万人疯抢 ,,2018年01月18日Intel搞定神经拟态芯片:模拟人类大脑、自主学习 ,,2018年01月18日阿里巴巴发布IoTConnect开放连接协议,盼推动语音互动入口普及 ,,2018年01月18日区块链火了,全球大佬们怎么看? ,,2018年01月18日Facebook正测试新功能主推本地新闻资讯 ,,2018年01月18日在GooglePlay中发现使用Kotlin开发的安卓恶意软件 ,,2018年01月18日VisualStudio201715.6预览版本2,增加新功能 ,,2018年01月18日百度陆奇:AI是5G最好的加速器 ,,2018年01月18日PinterestCEO:不同于谷歌和Facebook,我们走了第三条路 ,,2018年01月18日java面试题(51-70) 【编程语言】2015年04月28日虚幻4游戏开发_2_触发器 【系统运维】2015年06月11日chromium网络资源加载分析(一)主资源加载逻辑分析 【移动开发】2014年12月16日Python乱码,编码,repr,encode,decode探究 【综合】2015年03月30日poj3298Antimonotonicity贪心 【编程语言】2015年01月12日8.StringtoInteger(atoi)LeetcodePython 【编程语言】2015年01月29日16周(oj3) 【编程语言】2014年12月16日NGUI九宫格反向切割拉伸 【编程语言】2015年07月13日initcall_debug参数定位初始化过程的错误信息发生的位置 【编程语言】2015年02月13日Tokenize获取用分隔符标记的每个字符串【编程语言】2015年03月27日Linux下安装Matlab2014及破解【移动开发】2014年12月10日神级播放器MPC-HC历程回顾 ,,2017年07月27日【ActionScript】使用鼠标移动元件与元件相交判断函数hitTest 【编程语言】2015年06月17日mysql表之间的复制,同数据库和不同数据库 【编程语言】2014年12月09日Flex对象持久化2014年01月29日phpfile_get_contents抓取Gzip网页乱码的三种解决方法2014年01月29日photoshop最新版百度云下载地址【编程语言】2014年12月29日LeetCode:UniqueBinarySearchTreesII 【编程语言】2015年01月04日陈金凌实战分享:如何在1年内从PC端百度免费获取15-50万流量【综合】2015年07月02日Confluence5.6.5安装破解 【移动开发】2015年04月24日UVA-10785TheMadNumerologist【移动开发】2014年12月25日asp汉字中文图片验证码的实现代码2014年01月29日4月上旬中国域名总量净增10万余个期间增速放慢 【综合】2015年05月11日商业软件的“五个优先” 【编程语言】2015年03月03日win764位系统下的mysql5.6免安装版配置 【编程语言】2015年05月05日leetcode|RomantoInteger 【编程语言】2015年05月15日Pascal'sTriangle--LeetCode 【编程语言】2015年04月13日c++函数调用约定学习(二)【编程语言】2015年02月11日ApacheNiFiv0.7.0发布,一个易于使用、功能强大而且可靠的数据处理和分发系统 ,,2016年07月24日CP之改进 【编程语言】2015年04月27日
我们保证
We guarantee
> psd效果文件手工切图,保证图片效果最好体积最小利于传输
> 100%手写的HTML(DIV+CSS)编码,绝对符合W3C标准
> 代码精简、css沉余量小、搜索引擎扫描迅速,网页打开快捷
> 应用Css Sprite能够减少HTTP请求数,提高网页性能
> 跨浏览器兼容(IE6、7、8、9,Firefox火狐,Chrome谷歌)