第9章 继承和派生习题(详解)

在这里插入图片描述

一、选择题

1.下列表示引用的方法中, () 是正确的。已知:int m=10:

A.int &x=m; B.int &y=10; C.int &z; D.float &t=&m;

在C++中,引用是一个变量的别名。正确的引用声明方式应遵循C++的引用规则。选项分析:A.`int &x=m;` 这是一个正确的引用声明。`x` 成为 `m` 的引用,`x` 和 `m` 指向同一内存位置。B.`int &y=10;` 这是一个错误的引用声明。引用必须绑定到一个变量,不能直接绑定到字面值(如10)。C.`int &z;` 这是一个错误的声明。引用在声明时必须被初始化。D.`float &t=&m;` 这是一个错误的声明。首先,`&m` 获得的是变量 `m` 的地址,其类型是 `int*` 而不是 `float`。其次,`t` 应该直接绑定到一个 `float` 类型的变量,而不是一个地址。因此,正确的选项是:A.`int &x=m;`

2. 在以下类定义中, () 的虚基类

A)类B、类C是类A B)类A是类B、类C C)类B、类C是类D D)类A是类D

class A{
public: 
int x;
A(int a=0){x=a;}};
class B:public virtual A
{ ... };
class C:virtual public A
{  ... };
class D:public B,public C
{   	A x; 
public: 
int m; 
D(int a,int b,int c):B(a),C(b),x(c)  //F
...
};
在C++中,如果一个基类被多个直接或间接派生类通过不同的路径继承,
并且这个基类在继承路径中至少有一次是作为虚基类来继承的,那么这个基类就是虚基类。
如果一个基类包含另一个基类的指针或引用,那么这个基类就被称为虚基类。 选D

3.C++中的类有两种用法:一种是类的实例化,即生成类的对象,并参与系统的运行;另一种是通过 (),派生出新的类。

A.复用 B.继承C.单继承 D.多继承

继承允许新的类接收(或继承)一个或多个类的成员(包括数据成员和成员函数)。
这是代码复用的一个主要手段。选B

4.继承具有 () ,即当基类本身也是某一个类的派生类时,底层的派生类也会自动继承间接基类的成员。

A.规律性 B.传递性 C.重复性 D.多样性

B.传递性
这个特性确保了派生类能够从它的直接基类以及间接基类那里继承属性和方法,允许多层次的抽象和代码重用。

5.在多继承中,公有派生和私有派生对于基类成员在派生类中的可访问性与单继承的规则 () 。

A.完全相同 B.完全不同 C.部分相同,部分不同 D.以上都不对

在多继承中,公有派生和私有派生对于基类成员在派生类中的可访问性的规则与单继承中的规则是完全相同的。
无论是单继承还是多继承,
基类成员的访问控制(public, protected, private)都遵循相同的规则。因此,正确的答案是:
A.完全相同
公有继承(public inheritance)意味着基类的公有成员和保护成员在派生类中保持原有的访问权限,
而私有继承(private inheritance)意味着基类的所有成员在派生类中都变成了私有成员,
无论它们在基类中原来是什么访问权限。

6.派生类的构造函数的成员初始化列表中,不能包含 。

A.基类的构造函数 B.派生类中子对象的初始化
C.基类的子对象初始化 D.派生类中一般数据成员的初始化

在派生类的构造函数的成员初始化列表中可以包含以下元素:
A. 基类的构造函数 - 派生类的构造函数可以(并且在多数情况下应该)
在其成员初始化列表中调用基类的构造函数,以确保基类部分被正确初始化。
B. 派生类中子对象的初始化 - 如果派生类有类类型的成员(子对象),
则可以(也应该)在成员初始化列表中初始化它们。
C. 基类的子对象初始化 - 这一选项是有歧义的。如果指的是基类的成员(即基类中的子对象)
,那么这些在基类构造函数中被初始化,不应直接出现在派生类的成员初始化列表中。
但是,如果这里指的是由基类派生出的另一个基类的对象,
则派生类可以在其成员初始化列表中直接初始化这样的基类的子对象。
D. 派生类中一般数据成员的初始化 -派生类的构造函数的成员初始化列表当然可以包含派生类中一般数据成员的初始化。
因此,如果我们解释C为“基类中的子对象”,那么它是不能被派生类的构造函数的成员初始化列表直接初始化的,因为这是基类构造函数的责任。这样看来,C是正确的答案。如果解释C为“由基类派生的其他基类”,那么派生类是可以(并且应该)在其成员初始化列表中初始化这样的对象的。这里需要明确题目中“基类的子对象初始化”的具体含义。
选C

7. 定义派生类时,若不使用关键字显式地规定采用何种继承方式,则默认方式是 。

A. 私有继承 B. 非私有继承 C. 保护继承 D. 公有继承

A 私有继承

8. 在一个派生类的成员函数中,试图调用其基类的成员函数“void f();”,但无法通过编译。这说明 () 。

A. f()是基类的私有成员 B. f()是基类的保护成员
C. 派生类的继承方式是私有 D. 派生类的继承方式为保护

A f()是基类的私有成员

9. 有如下类定义:

class AA{
int a;
public:
AA(int n=0):a(n){}
};
class BB:public AA{
public;
BB(int n).......};

其中横线处缺失部分是 。
A.:a(n){} B.;AA(n){} C.{a(n)}; D.{a=n};

选项B `:AA(n){}` 正确的填写了类 BB 的构造函数,在初始化列表中调用了基类 AA 的构造函数,将 n 作为参数传递给它。这是正确的继承和初始化方式,能够确保派生类 BB 创建时,其基类 AA 的部分也得到了正确的初始化。以下是各个选项的解释:A. `:a(n){}` - 这是不合法的,因为 `a` 是基类 AA 的私有成员,不可以在派生类的初始化列表中直接初始化。B. `:AA(n){}` - 这是正确的。它使用基类的构造函数来初始化基类部分。C. `{a(n)};` - 这也是不合法的,因为像选项 A,`a` 是私有成员,不能在派生类中直接初始化或访问。D. `{a=n};` - 这同样是不合法的,因为 `a` 是基类的私有成员,不能在派生类中直接赋值。因此,正确答案是 B,它正确地使用了基类构造函数初始化基类成员变量。

10. 已知基类 Employee只有一个构造函数,其定义如下:

Employee::Employee(int n):id(n){}
Manager 是 Employee 的派生类,则下列对 Manager 的构造函数定义中,正确的是 。
A.Manager::Manager(int n):id(n){}
B.Manager::Manager(int n){id=n}
C.Manager::Manager(int n):Employee(n){}
D.Manager::Manager(int n){ Employee(n);}

C

11.有如下程序:

#include<iostream>
using namespace std;
class Base{
public;
void fun(){cout<'B';  }
};
class  Derived:public  Base{
public:
void fun()
{   .......        ;                                              
cout<<'D';
}
};
int main()
{  	Derived d;
d.fun();
return 0;
}

若程序的输出结果是 BD, 则画线处缺失的部分是 。
A.fun(); B.Base,fun(); C.Base::fun(); D.Base->fun();

C

12. 关于虚基类的描述中,错误的是 () 。

A, 使用虚基类可以消除由多继承产生的二义性
B. 构造派生类对象时,虚基类的构造函数只被调用一次
C. 声明“class B:virtual public A”,说明类 B为虚基类
D. 建立派生类对象时,首先调用虚基类的构造函数

C. 声明“class B:virtual public A”,说明类 B为虚基类这个描述是错误的。该声明实际上是指 A 是 B 的虚基类,而不是 B 是某个虚基类。当使用虚继承时,
类 A 将成为类 B 的虚基类,这样做是为了解决多重继承中可能出现的菱形继承问题,
其中一个类可能通过不同的路径多次继承同一个基类。

二、填空题

1. 如果类 A 继承了类 B, 那么类 A 被称为 (基) 类,而类 B 被称为 (派生) 类。
2 . C++的两种继承为: (公有继承) 和 (私有继承) 。
3. 在默认情况下的继承方式为(私有继承) 。
4. 从基类中公有派生一个类时,基类的公有成员就成为派生类的(公有) 成员,而这个基类的保护成员就成为派生类的 (保护) 成员。
5. C++提供了(多继承) 机制,允许一个派生类可以继承多个基类,甚至这些基类是互 不相关的。
6. 类X中的名字N 支配类Y中同名的名字N, 是指类X 以类Y 为它的一个基类,这称为 (支配规则) 。
7. 引进虚基类的目的是 (消除多重继承中由于继承同一个基类而产生的二义性和重复基类成员问题) 。
8. 在一个继承结构中,解决二义性的方法有 (虚继承) 和 (使用作用域运算符) 。

三、阅读程序题

1. 下列程序的输出结果是(3)

#include<iostream>
using namespace std;
class Base
{	int k;
public:void set(int n){k=n;}int get(){return k;}
};
class Derived:protected Base
{  	int j;
public:void set(int m,int n){Base::set(m);j=n;}int get(){return Base::get()+j; }
};
int main()
{Derived d;d.set(1,2);cout<<d.get()<<endl;return 0;
}

2,下列程序的输出结果是

#include<iostream>
using namespace std;
class A
{
public:A(){ cout<<"A";}~A(){cout<<"~A"; }
};
class B:public A
{	A *p;
public:B(){   cout<<"B";p=new A();}~B(){   cout<<"~B";delete p;}
};
int main()
{  	B obj;return 0;
}
程序的输出结果是 `ABAB~A~B~A`。下面是程序执行过程中的详细解释:1. 在main函数中,创建了一个`B`类的对象`obj`。
2. 调用`B`的构造函数`B()`,由于`B`继承自`A`,首先调用基类`A`的构造函数。
3. 输出`A`。
4. 然后执行`B`的构造函数体,输出`B`。
5. 在`B`的构造函数中,使用`new`创建了一个`A`类的对象,并将其地址赋值给指针`p`,因此会再次调用`A`的构造函数。
6. 输出`A`。
7. 程序接着会离开`B`构造函数的作用域,但此时对象`obj`的生命周期并未结束,故不会调用任何析构函数。
8. 当main函数执行完毕,`obj`的生命周期结束,此时会首先调用`B`类的析构函数`~B()`。
9. 输出`~B`。
10. 在`~B()`中,`delete p;`会删除之前构造函数中创建的`A`对象,因此调用`A`的析构函数。
11. 输出`~A`。
12. 跳出`~B()`的作用域,`B`的析构函数执行完毕,接着调用基类`A`的析构函数。
13. 输出`~A`。因此,整个程序的输出为`ABAB~A~B~A~A`。

3. 下列程序的输出结果是 。

#include<iostream>
using namespace std;
class A{
public:int x;A(){ x=100; }A(int  i){x=i; }void Show(){ cout<<"x="<<x<<'\t'<<"AA\n"; }
};
class B{
public:int y;B(){y=300;}B(int x){y=x; }void Show(){cout<<"y="<<y<<'\t'<<"BB\n";}
};
class C:public A,public B{
public:int y;C(int a,int b,int c):A(a),B(b){y=c; }void Show(){ cout<<"y="<<y<<'\t'<<"cc\n"; }
};
int  main()
{  	C c1(400,500,600);c1.y=200;c1.Show();c1.A::Show();c1.B::Show();return 0;
}

4. 下列程序的输出结果是

#include<iostream>
using namespace std;
class base
{
public:void who(){ cout<<"base class"<<endl;}
};
class derivel:public base
{
public:void who(){cout<<"derivel class"<<endl;}
};
class derive2:public base
{
public:void who(){cout<<"derive2 class"<<endl; }
};
void fun(base *p)
{   p->who();}
int main()
{   base obj1,*p;derivel obj2;derive2 obj3;fun(&obj1);fun(&obj2);fun(&obj3);obj2.who();obj3.who();return 0;
}
base class
base class
base class
derivel class
derive2 class
程序解释:base obj1,*p; 声明了基类 base 的一个对象 obj1 和一个指针 p。derivel obj2; 声明了派生类 derivel 的一个对象 obj2。derive2 obj3; 声明了派生类 derive2 的一个对象 obj3。fun(&obj1); 调用函数 fun 传入 base 类的对象地址,函数中的 p->who(); 调用的是基类 base 的 who 方法。fun(&obj2);fun(&obj3); 由于 fun 的参数类型是 base 类的指针,根据参数的静态类型,调用的也是 base 类的 who 方法。这里没有发生多态,因为 who 方法在基类中没有被声明为 virtual。最后,obj2.who(); 和 obj3.who(); 直接调用其各自类的 who 方法,因为这里是通过对象调用,不涉及多态。由于基类的 who() 方法没有被声明为虚函数 (virtual)fun() 函数中的 p->who() 调用不会展现多态行为(即不会根据对象的实际类型来调用对应的函数),而是会根据指针类型(基类 base)调用基类的 who() 方法。因此,前三次调用 fun() 都会输出 "base class"。而直接通过派生类对象调用 who() 时,则会调用相应派生类中的方法,分别输出 "derivel class""derive2 class"

三、编程题

1. 定义一个长方形 Rect 类,派生出长方体类 Cub, 计算派生类对象的表面积和体积。

#include <iostream>
using namespace std;
class Rect{public:double length;double width;Rect(double l,double w){length=l;width=w;}double area1(){return length*width;}
}; 
class Cub:public Rect{double height;public:Cub(double l,double w,double r):Rect(l,w){height=r;}double bs(){return 2*length*width+2*length*height+2*width*height;}double volume(){return area1()*height;}
};
int main(){Cub A(3,4,5);cout<<"表面积为:"<<A.bs()<<"体积为:"<<A.volume();
}
}

在这里插入图片描述

2. 定义一个 Shape 基类,并派生出圆球体(Sphere) 和立方体类(Cube), 分别求圆球体 与立方体对象的表面积和体积。

#include<iostream>
using namespace std;
class Shape {
protected: // protected允许子类访问double x, y;
public:Shape(double a, double b) {x=a;y=b;}double area() {return 0;} double volume() {return 0;}
};
class Sphere : public Shape {double radius;
public:Sphere(double d): Shape(d, d){radius=d;} // 调用基类构造函数并初始化radiusdouble area() {return 3.14 * radius * radius * 4;}double volume() {return 3.14 * radius * radius * radius * 4 / 3;}
};
class Cube : public Shape {double z;
public:Cube(double a, double b, double c) : Shape(a, b) {z=c;} // 调用基类构造函数并初始化zdouble area() {return 2 * (x * y + x * z + y * z);}double volume() {return x * y * z;}
};
int main() {Sphere A(1);cout << "圆球体的表面积为:" << A.area() << "\n"; cout << "圆球体的体积为:" << A.volume() << "\n"; Cube B(3, 4, 5);cout << "立方体的表面积为:" << B.area() << "\n"; cout << "立方体的体积为:" << B.volume() << "\n"; return 0;
}

在这里插入图片描述

3. 定义一个点类(Point)、矩形类(Rectangle和立方体类(Cube)的层次结构。矩形包括长度和宽度两个新数据成员,矩形的位置从点类继承。立方体类由长度、宽度和高度构成要求各类提供支持初始化的构造函数和显示自己成员的成员函数。编写主函数,测试这个层次结构,输出立方体类的相关信息。

#include<iostream>
using namespace std;
class Point//描述二维平面中一个点的类
{double x, y;
public:Point(float i=0, float j=0) { x=i; y=j;}double area( ) { return 0.0;}
};
class Rectangle:public Point
{float length;protected:float width;public:Rectangle(){length=0;width=0;} Rectangle(float l,float w){length=l;width=w;}float Area(){return length*width;}float GetL(){return length;}float GetW(){return width;}void RPrint(){cout<<"矩形的长为:"<<length;cout<<"\t宽为"<<width;}
};
class Cuboid:public Rectangle
{float high;public:Cuboid(){high=0;}Cuboid(float l,float w,float h):Rectangle(l,w){high=h;} void CPrint(){cout<<"长方体的长为:"<<GetL()<<"\t宽为:"<<width;cout<<"\t高为:"<<high<<"\t体积为:"<<high*Area()<<'\n';}
};
int main(){Rectangle r(10,5);r.RPrint();cout<<"\t面积为:"<<r.Area()<<'\n';Cuboid c(6,3,10);cout<<"矩形的长为:"<<c.GetL()<<"\t宽为:"<<c.GetW();cout<<"\t面积为:"<<c.Area()<<'\n';c.CPrint(); 
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/590066.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中利用Redis,ZooKeeper,数据库等实现分布式锁(遥遥领先)

1. 分布式锁 1.1 什么是分布式锁 在我们进行单机应用开发涉及并发同步的时候&#xff0c;我们往往采用synchronized或者ReentrantLock的方式来解决多线程间的代码同步问题。但是当我们的应用是在分布式集群工作的情况下&#xff0c;那么就需要一种更加高级的锁机制&#xff0…

合伙企业法关于合伙企业的要求

合伙协议可以载明合伙企业的经营期限和合伙人争议的解决方式。 合伙协议经全体合伙人签名、盖章后生效。合伙人依照合伙协议享有权利&#xff0c;承担责任。 经全体合伙人协商一致&#xff0c;可以修改或者补充合伙协议。 申请合伙企业设立登记&#xff0c;应当向企业登记机关提…

git rebase应用场景三

文章目录 git rebase应用场景三 git rebase应用场景三 在我们的开发分支中 假设我们修改一个文件 提交一个版本 再回到master分支 同时也去修改1.txt文件&#xff0c;提交一个版本 这样相当于master分支提交了一次&#xff0c;dev也提交了一次 然后回到dev分支 此时会报错…

事务失效的十种常见场景

学习事务失效场景 1 概述 事务的传播类型isolationTransactionnal注解属性 事务方法未被Spring管理方法使用final类型修饰非public修饰的方法同一个类中的方法相互调用方法的事务传播类型不支持事务异常被内部catch&#xff0c;程序生吞异常数据库不支持事务未配置开启事务错…

【ChatGPT 默认强化学习策略】PPO 近端策略优化算法

PPO 近端策略优化算法 PPO 概率比率裁剪 演员-评论家算法演员-评论家算法&#xff1a;多智能体强化学习核心框架概率比率裁剪&#xff1a;逐步进行变化的方法PPO 目标函数的设计重要性采样KL散度 PPO 概率比率裁剪 演员-评论家算法 论文链接&#xff1a;https://arxiv.org…

Oracle-深入了解cache buffer chain

文章目录 1.Cache buffer chain介绍2.Buffer cache的工作原理3 Buffer chains4.Multi-versioning of Buffers5.Latches6.诊断CBC latch等待7.解决 CBC Latch等待 1.Cache buffer chain介绍 经常看到会话等待事件“latch&#xff1a;cache buffers chain”。 如果想知道意味着什…

FA对接FC流程

2、FA进行对接 &#xff08;1&#xff09;首先安装好AD域控服务器DHCPDNS&#xff08;注意&#xff0c;不要忘记了做DNS正反向解析&#xff0c;就是把已经安装了ITA的主机做解析&#xff09;&#xff0c;在里面创建域用户 &#xff08;2&#xff09;安装ITA和VAG/VLB&#xf…

2024孙多勇®跨年演讲,重塑医美增长力,开启璀璨华章!

不谋万事者&#xff0c;不足谋一时&#xff1b;不谋全局者&#xff0c;不足谋一域。明者因时而变&#xff0c;智者随时而制。 12月31日-1月3日由汇成医美集团主办的&#xff0c;以“重塑医美增长力”为主题的第七届孙多勇跨年演讲暨「英雄2024」年度战略规划案&#xff0c;在中…

权威Scrum敏捷开发企业培训分享

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架。 这是一个两天的实训课程&#xff0c;面向研发管理者、项目经理、产品经理、研发团队等&#xff0c;旨在帮助学员全面系统地学习Scrum和敏捷开发, 帮助企业快速启动敏…

Excel模板填充:从minio上获取模板使用easyExcel填充

最近工作中有个excel导出的功能&#xff0c;要求导出的模板和客户提供的模板一致&#xff0c;而客户提供的模板有着复杂的表头和独特列表风格&#xff0c;像以往使用poi去画是非常耗时间的&#xff0c;比如需要考虑字体大小&#xff0c;单元格合并&#xff0c;单元格的格式等问…

Maya-UE xgen-UE 毛发导入UE流程整理

首先声明&#xff1a;maya建议用2022版本及一下&#xff0c;因为要用到Python 2 ,Maya2023以后默认是Python3不再支持Python2; 第一步&#xff1a;Xgen做好的毛发转成交互式Groom 第二步&#xff1a;导出刚生成的交互式Groom缓存&#xff0c;需要设置一下当前帧&#xff0c;和…

大数据与人工智能|全面数字化战略与企业数字化转型(第1节 )

要点一&#xff1a;培养跨学科思维 在分析时&#xff0c;需要采用多学科的思维方式 结果不重要&#xff0c;重要的是如何提炼现象、分析问题和得出结论的过程。 1. 介绍了锤子精神和多学科思维方式的重要性。指出了只从自身学科出发解决问题的局限性。 2. 提倡跨学科思维方式&a…

2023下半年的总结

我从八月下旬开始写的&#xff0c;到现在差不多有半年了&#xff0c;总结一下吧&#xff01; 1.计算机视觉 在计算机视觉方面&#xff0c;想必两个有名的深度学习框架&#xff08;TensorFlow和PyTorch&#xff09;大家都很清楚吧&#xff0c;以及OpenCV库。对于人脸识别&…

在高并发场景下,缓存“雪崩”了怎么办

1. 缓存雪崩的常见原因 缓存“雪崩”是指&#xff0c;因为部分缓存节点不可用&#xff0c;而导致整个缓存系统&#xff08;甚至是整个服务系统&#xff09;不可用。缓存“雪崩”主要分为以下两种情况&#xff1a; 因缓存不支持 rehash 而导致的缓存“雪崩”缓存支持 rehash 时…

电脑怎么检测手机配置信息

摘要 本文介绍了如何使用克魔助手工具在电脑上检测手机的配置信息。通过该工具&#xff0c;用户可以全面了解手机的硬件和操作系统信息&#xff0c;包括电池、CPU、内存、基带信息和销售信息等。 引言 在日常工作中&#xff0c;了解手机的配置信息对于开发和测试人员非常重要…

带大家做一个,易上手的家常蒜酱鲍鱼

超市有个福利鲍鱼 就买回来弄一下 搞一个整个的蒜 蒜去皮切末 三四个干辣椒切小末 切一点葱花混进去 鲍鱼去壳 去内脏&牙齿 将鲍鱼切块 因为鲍鱼是正经不好入味的东西 起锅烧油 下入 葱蒜干辣椒 翻炒出味 然后倒入鲍鱼进行翻炒 翻炒均匀后 倒入 一勺生抽 半勺老抽 …

Linux 内存数据 Metrics 指标解读

过去从未仔细了解过使用 free、top 等命令时显式的内存信息&#xff0c;只关注了已用内存 / 可用内存。本文我们详解解读和标注一下各个数据项的含义&#xff0c;同时和 Ganglia 显式的数据做一个映射。开始前介绍一个小知识&#xff0c;很多查看内存的命令行工具都是 cat /pro…

71内网安全-域横向网络传输应用层隧道技术

必备知识点&#xff1b; 代理和隧道技术的区别&#xff1f; 代理主要解决的是网络访问问题&#xff0c;隧道是对过滤的绕过&#xff0c; 隧道技术是为了解决什么 解决被防火墙一些设备&#xff0c;ids&#xff08;入侵检测系统&#xff09;进行拦截的东西进行突破&#xff0…

2023-12-11 LeetCode每日一题(最小体力消耗路径)

2023-12-11每日一题 一、题目编号 1631. 最小体力消耗路径二、题目链接 点击跳转到题目位置 三、题目描述 你准备参加一场远足活动。给你一个二维 rows x columns 的地图 heights &#xff0c;其中 heights[row][col] 表示格子 (row, col) 的高度。一开始你在最左上角的格…

自定义富集分析结果的term顺序

大家好&#xff0c;元旦过得还好吗&#xff1f;之前我们聊过如果富集分析结果不理想&#xff0c;如何选择富集分析的terms&#xff0c;如果不记得&#xff0c;可以看看这三个推文和视频。 ​富集分析结果不理想&#xff1a;如何从上千个term中找到自己想要所有term&#xff1f;…