ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【c++ primer】【18.3.5】构造函数与虚继承

2019-08-31 15:57:20  阅读:244  来源: 互联网

标签:初始化 ZooAnimal Bear 基类 18.3 primer Panda 构造函数


  在虚派生中,虚基类是由最底层的派生类初始化的。以我们的程序为例,当创建Panda对象时,构造函数独立控制ZooAnimal的初始化过程。

  为了理解这一规则,我们不妨假设当以普通规则处理初始化任务时会发生什么情况。在此例中,虚基类将会在多条继承路径上重复初始化。以ZooAnimal为例,如果应用普通规则,则Raccoon和Bear都会试图初始化Panda对象的ZooAnimal部分。

  当然,继承体系中每个类都有可能在某个时刻成为“最底层的派生类”。只要我们能创建最底层类的派生类对象,该派生类的构造函数就必须初始化它的虚基类。例如,在我们的继承体系中,当创建一个Bear(或Raccoon)的对象时,它已经处于派生类的最底层,因为Bear(或Raccoon)的构造函数将直接初始化其ZooAnimal基类部分: 

Bear::Bear(std::string name, bool onExhibit) : 
    ZooAnimal(name, onExhibit, "Bear") {}
Raccoon::Raccoon(std::string name, bool onExhibit) : 
    ZooAnimal(name, onExhibit, "Raccoon") {}

  而当创建一个Panda对象时,Panda位于派生的最底层并由它负责初始化共享的ZooAnimal的基类部分。即使ZooAnimal不是Panda的直接基类,Panda的构造函数也可以初始化ZooAnimal:

Panda::Panda(std::string name, bool onExhibit) : 
    ZooAnimal(name, onExhibit, "Panda"),
    Bear(name, onExhibit), 
    Raccoon(name, onExhibit), 
    Endangered(Endangered::critical),
    sleeping_flag(false) {}

虚继承的对象的构造方式

  含有虚基类的对象的构造顺序与一般的顺序稍有区别:首先使用提供给最底层派生类构造函数的初始值初始化该对象的虚基类子部分,接下来按照直接基类在派生类表中出现的次序依次对其进行初始化。

  例如,当我们创建Panda对象时:

  • 首先使用Panda的构造函数初始值列表中提供的初始值构造基类ZooAnimal部分。
  • 接下来构造Bear部分。
  • 然后构造Raccoon部分。
  • 然后构造第三个直接基类Endangered。
  • 最后构造Panda。

如果Panda没有显示地初始化ZooAnimal基类,则ZooAnimal的默认构造函数将被调用。如果ZooAnimal没有默认构造函数,则代码将发生错误。

构造函数与析构函数的次序

  一个类可以有多个虚基类。此时,这些虚的子对象将按照它们在派生列表中出现的顺序从左向右依次构造。例如,下面这个稍显杂乱的TeddyBear派生关系中有两个虚基类:ToyAnimal是直接虚基类,ZooAnimal是Bear的虚基类:

class Character {/* ... */};
class BookChracter : public Character {/* ... */};
class ToyAnimal {/* ... */};
class TeddyBear : public BookChracter,
                  public Bear, public virtual ToyAnimal
                  {/* ... */};

  编译器将按照直接基类的声明顺序对其依次进行检查,以确定其中是否含有虚基类。如果有,则先构造虚基类,然后按照声明的顺序逐一构造其它非虚基类。因此,要想创建一个TeddyBear对象,选哟按照如下次序调用这些构造函数:

ZooAnimal();        //Bear的虚基类
ToyAnimal();        //直接虚基类
Character();        //第一个非虚基类的间接基类
BookCharacter();    //第一个直接非虚基类
Bear();             //第二个直接非虚基类
TeddyBear();        //最底层的派生类

  合成的拷贝和移动构造函数按照完全相同的顺序执行,和成的赋值运算符中的成员也按照该顺序赋值。和往常一样,对象的销毁顺序与构造顺序正好相反,首先销毁TeddyBear部分,最后销毁ZooAnimal部分。

 

标签:初始化,ZooAnimal,Bear,基类,18.3,primer,Panda,构造函数
来源: https://www.cnblogs.com/bootblack/p/11439279.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有