| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 《C++ Primer》第18章 18.3节习题答案 -> 正文阅读 |
|
[C++知识库]《C++ Primer》第18章 18.3节习题答案 |
《C++ Primer》第18章 用于大型程序的工具 18.3节 多重继承与虚继承 习题答案 练习18.21:解释下列声明的含义,在它们当中存在错误吗?如果有,请指出来并说明错误的原因。
【出题思路】 理解多重继承的特性和规则。 【解答】 (b)错误,在一个派生列表中,同一基类只能出现一次,这里List出现了两次。 练习18.22:已知存在如下所示的类的继承体系,其中每个类都定义了一个默认构造函数:
对于下面的定义来说,构造函数的执行顺序是怎样的? MI mi; 【出题思路】 了解多重继承中构造函数的构造顺序。 【解答】 构造函数的执行次序如下: (1)A的构造函数 (2)B的构造函数 (3)C的构造函数 (4)X的构造函数 (5)Y的构造函数 (6)Z的构造函数 (7)MI的构造函数 练习18.23:使用练习18.22的继承体系以及下面定义的类D,同时假定每个类都定义了默认构造函数,请问下面的哪些类型转换是不被允许的?
【出题思路】 了解多个基类情况下类型转换的特点。 【解答】 (b)和(c)是不允许的。因为C对B的继承是私有继承,使得在D中B的默认构造函数成为不可访问的,所以尽管存在从“D*”到“B*”以及从“D*”到“A*”的转换,但这些转换不可访问。 练习18.24:在第714页,我们使用一个指向Panda对象的Bear指针进行了一系列调用,假设我们使用的是一个指向Panda对象的ZooAnimal指针将发生什么情况,请对这些调用语句逐一进行说明。 【出题思路】 深入理解基于指针类型的查找和调用顺序。 【解答】 如果使用ZooAnimal指针,则只能使用ZooAnimal类中定义的操作。 pb->print(count);,通过基类指针调用虚函数,使用动态绑定,pb目前指向Panda对象,随意调用Panda::print(ostream&)。 pb->cuddle();,因为ZooAnimal类中没有定义cuddle操作,所以该调用出错。 pb->highlight();,因为ZooAnimal类中没有定义highlight操作,所以该调用出错。delete pb;,因为ZooAnimal类中定义了虚析构函数,所以Panda类中的析构函数也是虚函数,因此delete pb;通过虚机制调用Panda析构函数。随着Panda析构函数的执行,依次调用Endangered、Bear和ZooAnimal的析构函数。 所以,通过指向Panda对象的Bear指针或ZooAnimal指针进行上述调用,将以同样方式确定函数调用。 练习18.25:假设我们有两个基类Base1和Base2,它们各自定义了一个名为print的虚成员和一个虚析构函数。从这两个基类中我们派生出下面的类,它们都重新定义了print函数:
通过下面的指针,指出在每个调用中分别使用了哪个函数:
【出题思路】 深入理解虚机制和指针类型调用的过程。 【解答】 (a)、(b)和(c)均通过基类指针调用虚函数print,这些基类指针当前都指向MI类对象,所以均调用MI::print();(d)、(e)和(f)均通过基类指针删除对象,这些基类指针当前都指向MI类对象,所以均通过虚机制调用MI析构函数,随着MI析构函数的执行,依次调用D2、Base2、D1和Base1的析构函数。 练习18.26:已知如上所示的继承体系,下面对print的调用为什么是错误的?适当修改MI,令其对print的调用可以编译通过并正确执行。
【出题思路】 了解通过类对象调用函数时需要注意的问题,并给出解决方案。 【解答】 因为mi.print(42);通过MI类对象调用print函数,编译器通过了名字查找,确定调用的是MI类中定义的print函数,但是MI类中定义的print函数需要std::vector<double>类型的参数,所以该调用是错误的。 改正:将MI中print的声明改为void print(int);,该print调用即可正确编译和执行。 练习18.27:已知如上所示的继承体系,同时假定为MI添加了一个名为foo的函数:
【出题思路】 深入理解多重继承体系下类的作用域和可见域。 【解答】
练习18.28:已知存在如下的继承体系,在VMI类的内部哪些继承而来的成员无须前缀限定符就能直接访问?哪些必须有限定符才能访问?说明你的原因。
【出题思路】 了解在类继承中不同派生类的优先级顺序。 【解答】 从VMI类内部可以不加限定地访问继承成员bar和ival。bar在共享基类Base和派生类Derived1中都存在,但这只是在一条派生路径上,特定派生类实例的优先级高于共享基类实例,所以在VMI类内部不加限定地访问bar,访问到的是Derived1中的bar实例。ival在共享基类Base和派生类Derived2中都存在;同理,在VMI类内部不加限定地访问ival,访问到的是Derived2中的ival实例。 继承成员foo和cval需要限定:二者在Derived1和Derived2中都存在,Derived1和Derived2均为Base的派生类,访问优先级相同,所以,在VMI类内不加限定地访问foo和cval,会出现二义性。 练习18.29:已知有如下所示的类继承关系:
【出题思路】 深入了解虚继承机制,析构函数和构造函数的执行顺序。 【解答】 (a)该类继承关系可表示如下: ? 如果定义Final对象,则创建该对象时按如下顺序调用构造函数:
注意,首先调用虚基类Base的构造函数(导致调用Class构造函数),然后按声明次序调用非虚基类的构造函数:首先是MI(),它导致调用D1()和D2(),然后是Class(),最后调用Final类的构造函数。 撤销Final对象时调用析构函数的次序与调用构造函数的次序相反,如下所示:
(b)一个Final对象只有一个Base子对象,有两个Class子对象。 (c)错误有
练习18.30:在Base中定义一个默认构造函数、一个拷贝构造函数和一个接受int形参的构造函数。在每个派生类中分别定义这三种构造函数,每个构造函数应该使用它的实参初始化其Base部分。【出题思路】 本题练习派生类中不同类型构造函数的初始化方法。 【解答】
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 6:09:29- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |