翘课被发现?C++老师如何通过“常函数”发现我没上课?

2023-11-10 17:50

本文主要是介绍翘课被发现?C++老师如何通过“常函数”发现我没上课?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 知识点一、使用sort函数对自定义类进行排序
      • 解读
      • 代码实现
    • 知识点二、常对象只能调用常函数

      这学期C++课的上机实验一共问了老师两次问题,而这两次都是早上睡懒觉睡过了没听课,漏掉了重要的知识点。结果两次问老师之后老师的回答是,“我怀疑你今天没来上课”,“你今天肯定没来上课”,甚至当我想敷衍过去的时候,老师再来追问我“是不是没来?”,实在是太尴尬了 ~ o ~。后来我思考了一下发现这两个问题其实是存在着一些共性的,都是关于常函数的知识,所以趁着期末复习的契机决定把这两次问的问题记录下来。

知识点一、使用sort函数对自定义类进行排序

      这题我疏漏的知识点为:对于自定义的类,若要调用sort函数对其进行排序,在运算符重载的时候,重载函数必须声明为常函数。

  • 题目:函数排序模板

    • 编写一个对n个元素的数组升序排序的函数模板mysort,其中元素类型可以是基本数据类型,也可以是点对象(按点到原点的距离比较)。
  • 输入

    • 第一行输入测试次数
    • 每次测试输入二行,第1行先输入一个大写字母表示数组类型,I表示整数类型,S表示字符串型,D表示双精度数类型,P表示点,最后输入n表示数组长度。第2行输入n个数据。
  • 输出

    • 每次测试输出一行排序后的结果
  • 样例输入
    4
    I 10
    15 3 51 27 9 35 78 14 65 8
    D 3
    -11.3 25.42 13.2
    P 6
    1.1 2.2 2.4 -6.5 12 32 1.2 1.3 -3.5 0.1 9.2 1.1
    S 4
    sandy david eason cindy

  • 样例输出
    3 8 9 14 15 27 35 51 65 78
    -11.3 13.2 25.42
    (1.2, 1.3) (1.1, 2.2) (-3.5, 0.1) (2*.4, -6.5) (9.2, 1.1) (12.0, 32.0)
    cindy david eason sandy

解读

  • 这题考察了两个知识点:
    • 一个是如何创建模板函数进行不同数据类型的排序。这部分其实就是使用"template < class T >"创建模板,然后在里面调用C++内置函数sort。再进行输出即可。
    • 第二个是对于自定义的类,若要调用sort函数对其进行排序,在运算符重载的时候,重载函数必须声明为常函数!!!
      • 比如该题中需要对坐标点Point类进行排序,因为要调用sort函数,而sort函数的底层实现实际上是对两个元素使用"<“符号进行比较,因此我们需要对”<"进行运算符重载。函数声明必须加上const!!!否则在自己电脑上可以运行。但是在oj平台上会出现奇怪的错误。
        • bool operator< (const Point& P)const{…} (√)
        • bool operator< (const Point& P){…} (×)

代码实现

#include <iostream>
#include <string> 	  //"string"用来表示字符串
#include <algorithm> 	  //"sort()"用来对数组进行排序
#include <math.h>  	  //"sqrt()"用来求平方根
#include <iomanip>	  //"fixed << setprecision(1)"用来确定输出小数点后几位 
using namespace std;//自定义点类
class Point {double x, y,distance;
public://输入点的数据void set() {cin >> x >> y;distance = sqrt(x * x +  y * y);}/*由于我们需要使用C++内置函数sort对自定义的类进行排序,sort函数的底层实现在比较两个元素谁大谁小的时候其实使用了“<”号,此我们需要对自定义类进行"<"号的运算符重载。*//*注意!我们必须声明常函数,即下面一行不能够写成" bool operator< (const Point& P)",必须要在后面加上一个const*/bool operator< (const Point& P)const{if (distance<P.distance)return 1;return 0;}//实际上sort函数只要重载"<"符号,但如果我们事先不知道要重载哪个符号,最好把"<",">","=="都重载上/*bool operator > ( Point  P)const{if (distance > P.distance)return 1;return 0;}bool operator == (Point& P)const{if (distance == P.distance)return 1;return 0;}*///输出运算符"<<"的重载friend ostream& operator<<(ostream &o,  Point &A) {o << fixed << setprecision(1) << "(" << A.x << ", " << A.y << ")";return o;}};//创造排序函数模板
template <class T>
void Sort(T*p, int num) {//调用C++内置函数进行排序sort(p, p + num);//进行输出for (int i = 0; i < num; i++) {cout << p[i] << " ";}cout << endl;
}int main()
{char c;		     //表示哪一种数据类型int t,num;	    	     //t:测试数据的次数,num:数组元素的个数cin >> t;while (t--) {cin >> c >> num;     //输入数组类型以及数组元素个数//int类型数组排序if (c == 'I') {    int *A = new int[num];for (int i = 0; i < num; i++) {cin >> A[i];}Sort<int> (A, num);}//string类型数组排序if (c == 'S') {string *A = new string[num];for (int i = 0; i < num; i++) {cin >> A[i];}Sort<string>(A, num);}//double类型if (c == 'D') {double *A = new double[num];for (int i = 0; i < num; i++) {cin >> A[i];}Sort<double>(A, num);}//Point类型(自定义)if (c == 'P') {Point *A = new Point[num];for (int i = 0; i < num; i++) {A[i].set();	//输入每个点的值}Sort<Point>(A, num);   }}return 0;
}

知识点二、常对象只能调用常函数

      与知识点一一样,也是涉及到常函数的知识。这里我疏漏的知识点是,如果类中某个函数中的参数为该类的常对象,那么这个常对象所调用的函数必须都声明为常函数(加一个const)

下图为当时遇到的问题,错误原因为我的常对象r调用的不是常函数的getfz(),因此无法通过编译。解决方法有两个:

  • 1.将"int getfz()"改成"int getfz() const"即可。
  • 2.将"const CFraction & r"改成"CFraction r"或者"CFraction & r",这样的话我们不使用常对象,就不强制要求使用常函数。
    在这里插入图片描述

这篇关于翘课被发现?C++老师如何通过“常函数”发现我没上课?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/384299

相关文章

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性:

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

解析C++11 static_assert及与Boost库的关联从入门到精通

《解析C++11static_assert及与Boost库的关联从入门到精通》static_assert是C++中强大的编译时验证工具,它能够在编译阶段拦截不符合预期的类型或值,增强代码的健壮性,通... 目录一、背景知识:传统断言方法的局限性1.1 assert宏1.2 #error指令1.3 第三方解决

C++11委托构造函数和继承构造函数的实现

《C++11委托构造函数和继承构造函数的实现》C++引入了委托构造函数和继承构造函数这两个重要的特性,本文主要介绍了C++11委托构造函数和继承构造函数的实现,具有一定的参考价值,感兴趣的可以了解一下... 目录引言一、委托构造函数1.1 委托构造函数的定义与作用1.2 委托构造函数的语法1.3 委托构造函