【C/C++笔试练习】继承和派生的概念、虚函数的概念、派生类的析构函数、纯虚函数的概念、动态编译、多态的实现、参数解析、跳石板

文章目录

  • C/C++笔试练习
  • 选择部分
    • (1)继承和派生的概念
    • (2)程序分析
    • (3)虚函数的概念
    • (4)派生类的析构函数
    • (5)纯虚函数的概念
    • (6)动态编译
    • (7)子类的析构函数
    • (8)多态的实现
    • (9)程序分析
    • (10)程序分析
  • 编程题 day13
    • 参数解析
    • 跳石板

C/C++笔试练习

选择部分

(1)继承和派生的概念

  下面叙述不正确的是()

  A. 派生类一般都用公有派生
  B. 对基类成员的访问必须是无二义性的
  C. 赋值兼容规则也适用于多重继承的组合
  D. 父类的公有成员在派生类中仍然是公有的

  答案:D

  在面向对象编程中,派生类是通过从一个或多个基类派生而来的。这里有几个关键概念和规则:

  派生方式:派生类可以从基类以公有(public)、保护(protected)或私有(private)的方式派生。这意味着基类的公有成员在派生类中仍然是公有的,保护成员在派生类中是保护的,私有成员在派生类中是不可访问的。

  考虑到这个规则,对于选项D,父类的公有成员在派生类中仍然是公有的,这个叙述是不正确的。应该是“父类的公有成员在派生类中仍然是公有的,而保护成员和私有成员不可访问”。

  访问基类成员:在派生类中访问基类的公有成员时,访问必须是明确且无二义性的。 这意味着如果基类有多个同名成员,那么在派生类中访问时必须明确指定是哪个基类的成员。所以选项B的叙述是正确的。

  赋值兼容规则:在多重继承的情况下,赋值兼容规则也适用。这意味着基类的类型可以被看作是派生类的类型。因此选项C的叙述是正确的。

  赋值兼容规则适用于多重继承:

class Base {};class D: public Base
{};int main()
{Base b;D d;
}

  (1)b=d; 子类对象可以复制父类无需转化。

  (2)Base* pd=&d; 子类对象地址可以直接赋给父类指针。

  (3)Base& rb=d; 可以使用子类对象对父类引用初始化,父类的公有成员在派生类仍为公有(前提是不是私有继承)。

  通常我们使用公有派生来创建派生类,因为这样可以使派生类具有和基类相同的接口,从而可以替换基类。 所以选项A的叙述是正确的。

  

(2)程序分析

  下面 C++ 程序的运行结果是()

#include <iostream>
using namespace stdclass parent {int i;
protected:int x;
public:parent() { x = 0; i = 0; }void change() { x++; i++; }void display();
};class son :public parent {
public:void modify();
};void parent::display() {cout << "x=" << x << endl;
}void son::modify() {x++;
}int main() {son A;parent B;A.display();A.change();A.modify();A.display();B.change();B.display();return 0;
}

  A.x=1 x=0 x=2
  B.x=2 x=0 x=1
  C.x=0 x=2 x=1
  D.x=0 x=1 x=2

  答案:C

son A;//创建子类A,先调用父类构造函数parent(),x=0,y=0,再调用子类构造函数,这里系统默认生成了一个
parent B;//创建父类B,直接调用构造函数parent(),x=0,y=0
A.display();//打印A的x  x=0A.change();//调用charge(),子类没有,去父类调用,x++,i++ 此时A的x=1,i=1
A.modify();//直接调用子类的modify(),x++,此时A的x=2,i=1
A.display();//打印A的x  x=2B.change();//直接调用父类的charge(),x++,i++, 此时B的x=1,i=1
B.display();//这里打印B中的成员变量x  x=1  故答案为 0 2 1 

在这里插入图片描述

  

(3)虚函数的概念

  关于虚函数的描述正确的是()

  A. 派生类的虚函数与基类的虚函数具有不同的参数个数和类型
  B. 内联函数不能是虚函数
  C. 派生类必须重新定义基类的虚函数
  D. 虚函数可以是一个static型的函数

  答案:B

  A选项提到派生类的虚函数与基类的虚函数可以有不同的参数个数和类型。这是不正确的。如果只看这个语义,派生类的虚函数与基类的虚函数没有什么关系。即使指的是相同的虚函数,那其中的参数列表(包括个数和类型)也必须是一样的。

  B选项说内联函数不能是虚函数。这是正确的。内联函数会展开,但是在虚标中存放的是函数地址,如果内联函数根据地址展开,就无法找到函数地址。所以内联函数不能是虚函数。

  C选项说派生类必须重新定义基类的虚函数。这是不正确的。如果基类的虚函数是纯虚函数(即没有实现),那么任何派生类都必须提供这个函数的实现。但如果基类的虚函数有实现,那么派生类可以选择是否重新定义这个函数。

  D选项说虚函数可以是一个static型的函数。这也是不正确的。虚函数需要this指针调用对象,调用虚表,而静态成员函数中没有this指针,所以不能被声明为虚函数。

  

(4)派生类的析构函数

  当一个类对象的生命周期结束后,关于调用析构函数的描述正确的是()

  A. 如果派生类没有定义析构函数,则只调用基类的析构函数
  B. 如果基类没有定义析构函数,则只调用派生类的析构函数
  C. 先调用派生类的析构函数,后调用基类的析构函数
  D. 先调用基类的析构函数,后调用派生类的析构函数

  答案:C

  在C++中,当一个对象被销毁时,其析构函数会被首先调用。如果这个对象是由一个派生类(子类)对象实例化的(前提是它的的析构函数是形成了多态),那么派生类的析构函数将首先被调用,然后是基类的析构函数。

  这个规则确保了派生类在基类之前释放任何由派生类管理的资源,以防止资源泄漏。 如果派生类没有定义析构函数,那么编译器会自动生成一个析构函数,这个析构函数只会调用基类的析构函数。如果基类也没有定义析构函数,那么编译器会为基类生成一个默认的析构函数。

  

(5)纯虚函数的概念

  以下关于纯虚函数的说法,正确的是()

  A. 声明纯虚函数的类不能实例化
  B. 声明纯虚函数的类成虚基类
  C. 子类必须实现基类的纯虚函数
  D. 纯虚函数必须是空函数

  答案:A

  A. 声明纯虚函数的类不能实例化 - 这是正确的。当一个类包含一个或多个纯虚函数时,它被称为抽象类。抽象类不能被实例化,只能被其他类继承。

  纯虚函数的定义:

virtual void fun()=0;

  B. 声明纯虚函数的类成虚基类 - 这是不正确的。虚函数和虚基类完全是两个概念,一个类包含纯虚函数并不影响它作为基类的类型。 只有当一个类作为虚基类使用时,它才需要至少一个纯虚函数。虚基类一般用于解决菱形继承。

  C. 子类必须实现基类的 - 这是不正确的。如果一个子类继承自一个包含纯虚函数的基类,那么子类不一定实现这些纯虚函数。多态实现,否则不实现。

  D. 纯虚函数必须是空函数 - 这是不正确的。纯虚函数只是声明,没有提供实现。它们在基类中的存在是为了让派生类实现它们。纯虚函数可以是任何类型的函数,包括带有实现的非空函数。

  

(6)动态编译

  下列描述,正确的一共有多少个()

  1)const char *p,这是一个常量指针,p的值不可修改
  2)在64位机上,char *p= “abcdefghijk”; sizeof( p )大小为12
  3)inline会检查函数参数,所以调用开销显著大于宏
  4)重载是编译时确定的,虚函数是运行时绑定的

  A. 1
  B. 2
  C. 3
  D. 4

  答案:A

  const char *p这是一个常量指针,p的值可以修改:const char *p是一个 指向常量的指针,这意味着你不能通过这个指针来改变它所指向的值,但你可以改变这个指针本身所指向的地址。

  在64位机上,char *p= “abcdefghijk”; sizeof( p )大小为12:这个描述是错误的。在64位机器上,一个指针的大小通常是8字节。所以sizeof(p)应该返回8,而不是12。

  inline会检查函数参数,所以调用开销显著大于宏:这个描述也是错误的。内联函数的主要目的是减少函数调用的开销,因为它可以避免进行一次函数调用的额外开销。但其实开销和宏也差不多,提不上显著的说法。

  重载是编译时确定的,虚函数是运行时绑定的:这个描述是正确的。重载是在编译时确定的(静态编译),编译器会根据函数名和参数类型在编译时确定调用哪个函数。而虚函数是在运行时动态绑定的(动态编译),编译器会生成一个虚函数表(vtable),并在运行时根据对象的实际类型来选择调用哪个虚函数的实现。

  

(7)子类的析构函数

  C++将父类的析构函数定义为虚函数,下列正确的是哪个()

  A. 释放父类指针时能正确释放子类对象
  B. 释放子类指针时能正确释放父类对象
  C. 这样做是错误的
  D. 以上全错

  答案:A

  在C++中,如果一个父类的析构函数被定义为虚函数,那么当通过父类指针释放一个子类对象时,能正确释放子类对象。这是因为虚析构函数的目的是为了在释放对象时正确地调用子类的析构函数。

  然而,如果子类的析构函数没有定义为虚函数,那么通过父类指针释放子类对象时,可能会导致子类的析构函数不被调用,从而造成资源泄漏。

  

(8)多态的实现

  下列关于多态性说法不正确的是()

  A. 多态性是指同名函数对应多种不同的实现
  B. 重载方式仅有函数重载
  C. 重载方式包含函数重载和运算符重载
  D. 多态性表现为静态和动态两种方式

  答案:B

  多态性是指同名函数对应多种不同的实现, 所以选项A是正确的。

  多态性有两种表现形式:编译时的多态性(静态)和运行时的多态性(动态)。编译时的多态性可以通过函数重载和运算符重载实现,所以选项C是正确的。运行时的多态性可以通过虚函数实现,所以选项D也是正确的。

  重载方式不只有函数重载,还包括运算符重载,所以选项B是不正确的。

  

(9)程序分析

  分析一下这段程序的输出

#include<iostream>
using namespace std;
class B
{
public:B(){cout << "default constructor" << " ";}~B(){cout << "destructed" << " ";}B(int i): data(i){cout << "constructed by parameter" << data << " ";}
private: int data;
};B Play( B b)
{return b;
}int main(int argc, char *argv[])
{B temp = Play(5);return 0;
}

A. constructed by parameter5 destructed destructed
B. constructed by parameter5 destructed
C. default constructor" constructed by parameter5 destructed
D. default constructor" constructed by parameter5 destructed destructed

  答案:A

class B
{
public:B(){cout << "default constructor" << " ";}~B()//6.最后调用析构函数,打印destructed{cout << "destructed" << " ";}B(int i) : data(i)//3.自动调用单参数构造函数,i=5,打印constructed by parameter5{cout << "constructed by parameter" << data << " ";}
private: int data;
};B Play(B b)//2.将5作为参数给B的构造函数  4.返回构造好的B对象,结束要调用一次析构, 打印destructed
{return b;
}int main(int argc, char* argv[])
{B temp = Play(5);//1.先调用Play()函数  5.返回的对象赋值给tempreturn 0;
}

在这里插入图片描述

  

(10)程序分析

  求输出结果

#include <iostream>
using namespace std;
class A
{
public:virtual void print(){cout << "A::print()" << "\n";}
};class B: public A
{public: 
virtual void print(){cout << "B::print()" << "\n";}
};class C: public A
{public: virtual void print(){cout << "C::print()" << "\n";}
};void print(A a)
{a.print();
}int main()
{A a, *aa, *ab, *ac;B b;C c;aa = &a;ab = &b;ac = &c;a.print();b.print();c.print();aa->print();ab->print();ac->print();print(a);print(b);print(c);
}

A. C::print() B::print() A::print() A::print() B::print() C::print() A::print() A::print() A::print()
B. A::print() B::print() C::print() A::print() B::print() C::print() A::print() A::print() A::print()
C. A::print() B::print() C::print() A::print() B::print() C::print() B::print() B::print() B::print()
D. C::print() B::print() A::print() A::print() B::print() C::print() C::print() C::print() C::print()

  答案:B

A a, * aa, * ab, * ac;//创建A对象a,和A类型指针aa,ab,ac 
B b;//实例化B对象b
C c;//实例化C对象c
aa = &a;//父类指针指向父类 A->A
ab = &b;//父类指针指向子类 A->B
ac = &c;//父类指针指向子类 A->C
//静态编译
a.print();//A对象直接调用A中成员函数print()  打印A::print()
b.print();//B对象直接调用B中成员函数print()  打印B::print()
c.print();//C对象直接调用C中成员函数print()  打印C::print()
//多态
aa->print();//父类对象直接调用父类函数print() 打印A::print()
ab->print();//父类指针A指向子类对象B,且为虚函数,实现多态  打印B::print()
ac->print();//父类指针A指向子类对象C,且为虚函数,实现多态  打印C::print()
//永远调用的是父类的函数
print(a);//父类对象A转入父类对象A  打印A::print()
print(b);//子类对象B传入父类对象A  打印A::print()
print(c);//子类对象C传入父类对象A  打印A::print()

在这里插入图片描述

            

编程题 day13

参数解析

参数解析

  本题通过以空格和双引号为间隔,统计参数个数。对于双引号,通过添加flag,保证双引号中的空格被输出。

#include<iostream>
#include<string>
#include<vector>
using namespace std;void cmdLineParse(const string& str) 
{string tmp = "";vector<string> svec;bool flag = false; //用于判断是否处于字符串的状态for (int i = 0; i < str.size(); ++i) {if (str[i] == '"') { //判断是否是字符串的起始或者结束flag = !flag; //说明处于了字符串的状态} else if (str[i] == ' ' &&!flag) { //判断参数的分隔或者是否为字符串的内容svec.push_back(tmp);tmp = "";} else { //正常的参数内容tmp += str[i]; //xcopy}}//追加最后一个参数svec.push_back(tmp); cout << svec.size() << endl;for (int i = 0; i < svec.size(); ++i)cout << svec[i] << endl;
}int main() 
{string str;while (getline(cin, str)) {cmdLineParse(str);}return 0;
}

  

跳石板

跳石板

  将1 - M个石板看做一个结果数组stepNum,每个stepNum[i]储存着从起点到这一步最小的步数,其中0为不能到达。 从起点开始对stepNum进行遍历,先求i的所有约数(即从stepNum[i]能走的步数),然后更新那几个能到达的位置的最小步数。如果不能到达则更新为此时位置的最小步数 + 1,如果是能到达的就更新为min(已记录的最小步数,此处的最小步数 + 1)),遍历一遍后得到结果。

#include<iostream>
#include<vector>
#include<limits.h>
#include<math.h>
using namespace std;void get_div_num(int v, vector<int>& a) 
{for (int i = 2; i <= sqrt(v); ++i){if (v % i == 0) {a.push_back(i);if (v / i != i)a.push_back(v / i);}}
}int Jump(int n, int m) 
{vector<int> step(m + 1, INT_MAX); //int_max表示不可达到step[n] = 0; //当前位置初始化for (int i = n; i < m; ++i){if (step[i] == INT_MAX)continue;vector<int> a;//获取i的约数,并保存get_div_num(i, a);for (int j = 0; j < a.size(); ++j){if (a[j] + i <= m && step[a[j] + i] != INT_MAX) {//需要挑选一个最小值step[a[j] + i] = step[a[j] + i] < step[i] + 1 ? step[a[j] + i] : step[i] + 1;} else if (a[j] + i <= m) {step[a[j] + i] = step[i] + 1;}}}return step[m] == INT_MAX ? -1 : step[m];
}int main()
{int n, m, min_step;while (cin >> n >> m) {min_step = Jump(n, m);cout << min_step << endl;}return 0;
}

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

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

相关文章

uniapp App 端 版本更新检测

function checkVersion() { var req { //升级检测数据 appid: plus.runtime.appid, version: plus.runtime.version }; const timestamp Date.parse(new Date()); config.server.query_news uni.reque…

LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字

上一节实现了 LangChain 实现给动物取名字&#xff0c; 实际上每次给不同的动物取名字&#xff0c;还得修改源代码&#xff0c;这周就用模块化template来实现。 1. 添加promptTemplate from langchain.llms import OpenAI # 导入Langchain库中的OpenAI模块 from langchain.p…

优思学院|什么是精益生产管理?从一个生活上的故事出发来说明。

你关掉电脑&#xff0c;离开办公室。 一个小时后&#xff0c;你进入家门和孩子们在一起。 你和家人一起吃晚饭。 你的老板打电话来查看你的项目进展。 你哄孩子入睡并给他们读个故事。 作为一个负责任的父母&#xff0c;你想要与孩子们的互动时间增加并提高生活的质量&…

ChatGPT + DALL·E 3

参考链接&#xff1a; https://chat.xutongbao.top/

Linux中安装部署环境(JAVA)

目录 在Linux中安装jdk 包管理器yum安装jdk JDK安装过程中的问题 验证安装jdk 在Linux中安装tomcat 安装mysql 在Linux中安装jdk jdk在Linux中的安装方式有很多种, 这里介绍最简单的方法, 也就是包管理器方法: 包管理器yum安装jdk Linux中常见的包管理器有: yumaptp…

图论| 827. 最大人工岛 127. 单词接龙

827. 最大人工岛 题目&#xff1a;给你一个大小为 n x n 二进制矩阵 grid 。最多 只能将一格 0 变成 1 。返回执行此操作后&#xff0c;grid 中最大的岛屿面积是多少&#xff1f; 岛屿 由一组上、下、左、右四个方向相连的 1 形成。 题目链接&#xff1a;[827. 最大人工岛](ht…

前端为什么要工程化

前端为什么要工程化 文章目录 前端为什么要工程化传统开发的弊端一个常见的案例更多问题 工程化带来的优势开发层面的优势团队协作的优势统一的项目结构统一的代码风格可复用的模块和组件代码健壮性有保障团队开发效率高 求职竞争上的优势 现在前端的工作与以前的前端开发已经完…

深度学习交通车辆流量分析 - 目标检测与跟踪 - python opencv 计算机竞赛

文章目录 0 前言1 课题背景2 实现效果3 DeepSORT车辆跟踪3.1 Deep SORT多目标跟踪算法3.2 算法流程 4 YOLOV5算法4.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; *…

Linux 时区设置

对于服务器来说&#xff0c;linux的时区影响着运行之上的数据库和后端程序的时区 应该和数据库和后端及其他程序的时区保持一致 其他相关时区的设置 pgsql时区设置&#xff1a; php时区设置&#xff1a; 1.显示当前的时间和时区 date结果类似下面&#xff0c;图中显示的是ut…

球幕投影有哪些常见的物理表现形式?

近年来&#xff0c;投影技术不断发展完善&#xff0c;给内容的表达方式带来了突破&#xff0c;使其展示形式不再局限于平面&#xff0c;即使在弧面、球面等异形幕墙上&#xff0c;也能呈现出令人惊叹的视觉画面。其中球幕投影备受关注&#xff0c;它以半球形屏幕将图像投影到球…

Selenium安装WebDriver(含116/117/118/119)

1、确认浏览器的版本 在浏览器的地址栏&#xff0c;输入chrome://version/&#xff0c;回车后即可查看到对应版本 2、找到对应的chromedriver版本 2.1 114及之前的版本可以通过点击下载chromedriver,根据版本号&#xff08;只看大版本&#xff09;下载对应文件 2.2 116版…

解决 VS2022 关于 c++17 报错: C2131 表达式必须含有常量值

使用 VS2022 编译 ORB-SLAM3 加载Vocabulary 二进制ORBvoc.bin 时&#xff0c;在 DBOW2 里修改 TemplatedVocabulary.h 代码显示这样的错误&#xff1a; 编译器错误 C2131 表达式的计算结果不是常数 定位到我的代码中&#xff1a; char buf [size_node] ; 原因 &#xff1a; …

PyTorch - 高效快速配置 Conda + PyTorch 环境 (解决 segment fault )

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/134463035 在配置算法项目时&#xff0c;因网络下载速度的原因&#xff0c;导致默认的 conda 与 pytorch 包安装缓慢&#xff0c;需要配置新的 co…

zabbix-proxy分布式监控

Zabbix是一款开源的企业级网络监控软件&#xff0c;可以监测服务器、网络设备、应用程序等各种资源的状态和性能指标。在大型环境中&#xff0c;如果只有一个Zabbix Server来监控所有的节点&#xff0c;可能会遇到性能瓶颈和数据处理难题。 为了解决这个问题&#xff0c;Zabbi…

美创科技与南京大数据安全技术有限公司达成战略合作

近日&#xff0c;美创科技与南京大数据安全技术有限公司正式签署战略合作协议&#xff0c;优势力量共享、共拓共创共赢。 美创科技CEO柳遵梁、副总裁罗亮亮、副总裁王利强&#xff0c;南京大数据安全技术有限公司总经理潘杰、市场总监刘莉莎、销售总监王皓月、技术总监薛松等出…

快速上手 TypeScript

什么是TypeScript TypeScript 简称 TS &#xff0c;既是一门新语言&#xff0c;也是 JS 的一个超集&#xff0c;它是在 JavaScript 的基础上增加了一套类型系统&#xff0c;它支持所有的 JS 语句&#xff0c;为工程化开发而生&#xff0c;最终在编译的时候去掉类型和特有的语法…

STM32电源名词解析

先来简单了解一下各种电源端口的命名 VCC&#xff1a;Ccircuit 表示电路的意思, 即接入电路的电压 VDD&#xff1a;Ddevice 表示器件的意思, 即器件内部的工作电压。 VSS&#xff1a;Sseries 表示公共连接的意思&#xff0c;通常指电路公共接地端电压。 GND&#xff1a;在电…

Eclipse切换中文环境

PACK包链接 地址&#xff0c;进入后可以看到不同版本的包。 要选择跟自己Eclipse版本一致的包&#xff0c;比如我的Eclipse启动界面如下&#xff0c;我就要找Helios的包&#xff08; Juno、Indigo、Helios、Kepler这些具体怎么划分的我也不清楚&#xff09;。 在线安装 打…

七、Nacos和Eureka的区别

一、nacos注册中心 二、临时实例与非临时实例 三、区别 Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式&#xff0c;非临时实例采用主动检测模式临时实例心跳不正常会被剔除&#xff0c;非临时实例则不会被剔除Nacos支持服务列表变更的消息推送模式&#xff0c;服务…