目录

类的辅助函数(Helper Functions)

类与数组


类的辅助函数(Helper Functions)

类 可以具有不仅仅是设置 或 获取数据值的成员函数。这些 辅助函数 可以执行经常被请求或在类本身中更容易执行的任务。

例如:

假设我们有一个班级来跟踪学生在课程中获得的成绩。 我们可以创建一个计算平均值的成员函数。

/*header file for main.cpp*/
#include<iostream>
using namespace std;class Student
{int grade[5];int id;
public:Student();void setId(int idin);void setGrade(int index, int gradeIn);int getId();int getGrade(int index);float getAvg();void printInfo();
};Student::Student()
{for(int i=0;i<5;i++){grade[i] = 0;}id = 0;
}void Student::setId(int idin)
{id = idin;
}
void Student::setGrade(int index, int gradeIn)
{grade[index] = gradeIn;
}
int  Student::getId()
{return id;
}
int  Student::getGrade(int index)
{return grade[index];
}
float  Student::getAvg()
{int sum = 0;for(int i=0; i<5;i++)sum = sum + grade[i];return sum/5.0;
}
void Student::printInfo()
{cout<<id<<"\n";for(int i=0; i<5;i++)cout<<grade[i]<<" ";
}

上面是头文件 main.hpp 。

#include "main.hpp"int main()
{Student s1;s1.setId(3232);s1.setGrade(0,85);s1.setGrade(1, 80);s1.setGrade(2,98);s1.setGrade(3,65);s1.setGrade(4,90);s1.printInfo();cout<<"avg = "<<s1.getAvg();return 0;
}

运行结果:

相信大家学到这里,应该在学习创建类的时候就可以想到类的函数(也即是类的方法)可以变成自己辅助函数了,非常有趣。

这里有个需要注意的技术点:

1。int grade[5]; 注意这里的是定义了索引为5 的整型数组,也就是:grade[0],grade[1],grade[2],grade[3],grade[];

2。这个是构造函数,这里的 for 语句,主要是为了给 grade[i] 从 0到4 的5个索引下的值初始化为0,注意它的 for 书写格式。相信学过其他程序语言的程序员都能够看懂,我就不赘(zhuì)述了(不查不知道,一查吓一跳!这个赘述的赘(zhuì),很多线上或者线下的培训老师都读成 ào 或者 ǒu)。

Student::Student()
{for(int i=0;i<5;i++){grade[i] = 0;}id = 0;
}

我们再来看一个例子:

对于这个程序,我创建了一个名为 ' Gameboard ' 的类。

Gameboard 有一个私有成员 ' gameSpace [4] [4] ',它是一个 4x4 数组,可以接受16个位置中每个位置的字符。

该类有四个公共成员,它们是函数和构造函数:

  • 构造函数将 gameSpace 的每个值设置为 char值 ' - ' ;
  • 每个位置用一个 char 设置;
  • 每个位置都可以单独阅读;
  • printInfo 将 gameSpace 打印为 4x4 矩阵;
  • 辅助函数 ' fourInRow ' 检查每一行,寻找四个 ' x ' 。 当它在同一行中找到四个 x 时,它返回一个 ' 1 ',否则返回一个' 0 '。
#include <iostream>
#include <iomanip>
using namespace std;class Gameboard
{char gameSpace[4][4];
public:Gameboard(); //initialize the board with '-' in all 16 spacesvoid setGameSpace(int row,int column, char value); //x,y,or '-' in each game squarechar getGameSpace(int row,int column);int fourInRow(); //four 'x's in any row 'wins'void printInfo(); //print the game board in a 4x4 matrix
};//TODO: complete the class definition
Gameboard::Gameboard()
{for(int i=0;i<4; i++)for(int j=0;j<4; j++){gameSpace[i][j] = '-';}
}void Gameboard::setGameSpace(int row,int column,char value)
{gameSpace[row][column] = value;
}char Gameboard::getGameSpace(int row,int column)
{return gameSpace[row][column];
}int Gameboard::fourInRow()
{int count;for(int i=0;i<4; i++){count = 0;for(int j=0;j<4; j++){if(gameSpace[i][j]=='x'){count++;//cout<<"count = "<<count;}}if(count == 4)return 1;}return 0;
}
void Gameboard::printInfo()
{cout<<std::setw(5);cout<<"\n";for(int i=0;i<4; i++){for(int j=0;j<4; j++){cout<<gameSpace[i][j];}cout<<"\n";}
}

以上是头文件main.hpp。

#include "main.hpp"int main()
{Gameboard game1;game1.setGameSpace(0,0,'x');game1.setGameSpace(0,1,'x');game1.setGameSpace(0,2,'x');game1.setGameSpace(0,3,'y');game1.setGameSpace(1,0,'x');game1.setGameSpace(2,0,'x');game1.setGameSpace(3,0,'x');game1.setGameSpace(3,1,'x');game1.setGameSpace(3,2,'x');game1.setGameSpace(3,3,'x');if(game1.fourInRow() == 1){cout<<"X got four in a row! \n\n";}else{cout<<"X did not get four in a row :(\n\n";}game1.printInfo();return 0;
}

运行结果:

代码解析:

1。 #include <iomanip>  这里使用了manip,manip是manipulator(操纵器)的缩写(在c++上只能通过输入缩写才有效),主要是对cin,cout之类的一些操纵运算子,比如setfill,setw,setbase,setprecision等等。

2。对比两个双循环语句:

第一个:

Gameboard::Gameboard()
{for(int i=0;i<4; i++)for(int j=0;j<4; j++){gameSpace[i][j] = '-';}
}

第二个:

void Gameboard::printInfo()
{cout<<std::setw(5);cout<<"\n";for(int i=0;i<4; i++){for(int j=0;j<4; j++){cout<<gameSpace[i][j];}cout<<"\n";}
}

能看出什么区别吗?是的,上面第一个代码的第一for没有花括号,而第二个代码有花括号,其实两种都是可以的,但推荐第二种。是比较严谨的写法。这里有关数组 gameSpace[i][j] 的知识,后面文章会讲到。

3。以下这段代码,第一个注意,count = 0; 放在第一个 for 循环里面是为了让每次循环结束一行后,让 count 重新为 0 。

第二个注意:count++; 它表示:count = count + 1。

第三个注意:注意双重 for 循环和 if 的搭配,注意格式和位置。

int Gameboard::fourInRow()
{int count;for(int i=0;i<4; i++){count = 0;for(int j=0;j<4; j++){if(gameSpace[i][j]=='x'){count++;//cout<<"count = "<<count;}}if(count == 4)return 1;}return 0;
}

类与数组

用户定义的对象可以像使用任何其他对象一样使用。

例如,我们可以在数组中使用用户定义的对象。 这可能有点棘手,所以让我们通过使用数组来练习使用类。

在这个程序中,我们使用前面示例中的 Student类 来创建课程。 我们将使用数组来创建课程,当然每个元素都是Student的实例。

#include<iostream>
using namespace std;class Student
{int grade[5];int id;
public:Student();void setId(int idin);void setGrade(int index, int gradeIn);int getId();int getGrade(int index);int getAvg();void printInfo();
};Student::Student()
{for(int i=0;i<5;i++){grade[i] = 0;}id = 0;
}void Student::setId(int idin)
{id = idin;
}
void Student::setGrade(int index, int gradeIn)
{grade[index] = gradeIn;
}
int  Student::getId()
{return id;
}
int  Student::getGrade(int index)
{return grade[index];
}
int  Student::getAvg()
{int sum = 0;for(int i=0; i<5;i++)sum = sum + grade[i];return sum/5.0;
}
void Student::printInfo()
{cout<<id<<"\n";for(int i=0; i<5;i++)cout<<grade[i]<<" ";
}

以上是头文件main.hpp。

#include "main.hpp"int main()
{const int SIZE= 3;//Create a course of studentsStudent course1[SIZE];//Each array element is a Student type//so it has access to the members of Studentcourse1[0].setId(1000);course1[1].setId(1111);course1[2].setId(2222);course1[0].setGrade(0,83);course1[1].setGrade(0,95);course1[2].setGrade(0,72);course1[0].setGrade(1,87);course1[1].setGrade(1,52);course1[2].setGrade(1,70);course1[0].setGrade(2,90);course1[1].setGrade(2,85);course1[2].setGrade(2,82);for(int i=0;i<SIZE;i++){course1[i].printInfo();cout<<"\n\n";}return 0;
}

运行结果:

代码解析:

1。const int SIZE= 3; 这个代码指定SIZE为整型并赋值为3,这时候,你可能又会问:为什么前面要加const ?

const 是 constant 的缩写,本意是不变的,不易改变的意思。

const 在C++中是用来修饰 内置类型变量,自定义对象,成员函数,返回值,函数参数

还是上码吧,这样比较直观。

第一:const 修饰普通类型的变量。

#include<iostream>int main(){const int  a = 12;int  b = a;        //可以赋值给b;a = 100;           // 这里会出现错误;
}

运行结果:

提示了错误信息,这里 a 被定义为一个常量,并且可以将 a 赋值给 b是可以的。但是 a 的值不允许修改,因为它被编译器认为是一个常量。

我们接着看第二个例子:

#include<iostream>using namespace std;int main(void)
{const int  a = 12;int  *p = (int*)&a;*p = 8;cout<<a;system("pause");return 0;
}

运行结果:

上面代码解析:

1。int main(void){},这括号里面为什么会有void?为什么很多东西都跟void扯上关系?

一般来说,二者没有区别,因为 mian函数 是主入口函数,一般也没有其他函数会调用 mian函数,要求 mian函数 返回一个值,同时,我们也不会在 main函数 定义中放入形参变量,这是因为我们使用 main函数 仅是为了提供了程序执行的入口,所以通常都会写void main(void){},或者就是 main(){} 。

不过,从函数定义来说,或者代码的健壮性角度来说,不管是 main函数 还是其他函数,应该要声明其函数返回值类型,函数形参类型等,这些都是为了保证代码安全,因此有些编译器,会把代码检查等级设置较高,不允许出现类似 main() 这样的函数写法,所以,从这个层面上,我建议你还是写成 int mian(void){} 这样的形式,至少这样的形式,一般的编译器都不会报错的。

2。int  *p = (int*)&a; ,这里的 (int*)&a 是什么意思?

首先,我们要知道 (int*)a 是什么!(int*)a 将 指针变量a 强制转换为 整型指针。那么 (int*)a int*a 是一样的吗? 没错,不一样。int*a只是定义一个 整型的 指针变量a 。

那么 (int*)&a 是什么?它是先取a的地址,把其转换成 int型 的指针。

那么 *(int*)&a 是什么?它是先取a的地址,把其转换成 int型 的指针,再取指针 指向的值。

3。system("pause"); ,这也是什么意思哦?

"pause" 是 Dos 的系统命令,system是 C 函数,调用系统命令,整体作用是让窗口等待一个回车。

结果解析:

对于 const变量a,我们取变量的地址并转换赋值给 指向int的指针,然后利用*p = 8; 重新对 变量a 地址内的值赋值,然后输出查看a的值。从下面的调试窗口看到a的值被改变为8,但是输出的结果仍然是7。

从结果中我们可以看到,编译器然后认为a的值为一开始定义的7,所以对const  a的操作就会产生上面的情况。所以千万不要轻易对const变量设法赋值,这会产生意想不到的行为。

如果不想让编译器察觉到上面到对const的操作,我们可以在const前面加上 volatile 关键字。Volatile 关键字跟 const 的意思相反,是易变的,容易改变的意思。所以不会被编译器优化,编译器也就不会改变对a变量的操作。

#include<iostream>
using namespace std;int main(void)
{volatile const int  a = 12;int  *p = (int*)&a;*p = 8;cout<<a;system("pause");return 0;
}

运行结果:

关于Const函数,后面会进行更加详细的了解。

现在回来我们那个类的例子:

2。注意 Student course1[SIZE]; 这里使用了数组,是从 0 开始的。然后类似于course1[0].setGrade(0,83);,可能刚看的时候不熟悉这种思路,建议你心里建立一个Excel表去思考它,会有一些帮助。

提示:course1[0],[1],[2]; 这些表示行,setGrade(0, 83); 这些表示列 和 分数)

    const int SIZE= 3;//Create a course of studentsStudent course1[SIZE];//Each array element is a Student type//so it has access to the members of Studentcourse1[0].setId(1000);course1[1].setId(1111);course1[2].setId(2222);course1[0].setGrade(0,83);course1[1].setGrade(0,95);course1[2].setGrade(0,72);course1[0].setGrade(1,87);course1[1].setGrade(1,52);course1[2].setGrade(1,70);course1[0].setGrade(2,90);course1[1].setGrade(2,85);course1[2].setGrade(2,82);

算法和数据结构就是编程的一个重要部分,你若失掉了算法和数据结构,你就把一切都失掉了。

C ++ 类 | 类的辅助函数(Helper Functions) ,类与数组_3相关推荐

  1. 业务逻辑层的Helper基类

    业务逻辑(BLL)层的组织,长期以来一直是个困惑.打从开始引入ORM后,BLL层不再出现SQL语句和存储过程,感觉思路清晰了不少,现在自己对BLL结构认识大致上定型,一般根据不同方面的业务逻辑,对应不 ...

  2. oop 类和对象的_实用程序类的OOP替代

    oop 类和对象的 实用程序类(也称为帮助程序类)是仅具有静态方法且不封装状态的"结构". StringUtils , IOUtils , FileUtils从Apache的共享 ...

  3. 派生类参数初始化列表和基类构造函数顺序

    今天被问到了一个问题,随便回了一句,父类还没有构建,怎么能初始化父类的成员. 派生类构造函数的参数初始化列表,为什么不能初始化基类的成员? 例如下面的是不可以的 class Rectangle : p ...

  4. C++ 笔记(16)— 类和对象(类定义、类实例对象定义、访问类成员、类成员函数、类 public/private/protected 成员、类对象引用和指针)

    1. 类的定义 类定义是以关键字 class 开头,后跟类的名称.并在它后面依次包含类名,一组放在 {} 内的成员属性和成员函数,以及结尾的分号. 类声明将类本身及其属性告诉编译器.类声明本身并不能改 ...

  5. python如何创建一个类_python (知识点:类)简单的创建一个类

    #!/usr/bin/env python # -*- coding: utf-8 -*- """ Created on Mon Nov 14 01:01:29 2016 ...

  6. java封装对象实体类_Java 接口自动化系列--实体类之entity封装

    实体包entity下面有4个类,主要存放java对象,每个类必须有私有属性,空参构造,get set方法 具体excel中数据信息见---工具类excel文章 1.API类 解析excel中接口信息的 ...

  7. java 类定义_JAVA类与对象(二)----类定义基础

    类是组成java程序的基本要素,是java中的一种重要的复合数据类型.它封装了一类对象的状态和方法,是这一类对象的原型.一个类的实现包括两个部分:类声明和类体,基本格式: class { 属性 方法 ...

  8. 两个类相互包含引用的问题--类前向声明

    在构造自己的类时,有可能会碰到两个类之间的相互引用问题,例如:定义了类A类B,A中使用了B定义的类型,B中也使用了A定义的类型 class A {     int i;     B b; } clas ...

  9. java平台类成员访问修饰符_JAVA类的修饰符及访问权限

    1.类 外部类      class前的修饰符只能有public final abstrct 无(默认) :同包可见  (Eclipse中选择package) 内部类      class前的修饰符有 ...

最新文章

  1. 线程使用 c语言,如何用C语言实现多线程
  2. Thinkpad系统重装终极版
  3. echarts setoption方法_在Vue和React中使用ECharts的多种方法
  4. mysql 事务关联_MySQL 关联、联合查询,事务ACID见解
  5. Python 实例属性和类属性
  6. mysql对本地文件的读取_Mysql 任意读取客户端文件
  7. 让UpdatePanel支持文件上传(4):数据传输与解析机制
  8. HbuilderX 左侧项目栏文件位置和打开的文档同步(对应显示) - 设置篇
  9. matlab fdtd,fdtd(fdtd中文教程)
  10. 大乐透python预测程序_Python生成随机验证码,大乐透号码
  11. mac tree命令
  12. php进度台帐管理系统,捷雅途 - 工程量0号台账管理系统快速操作说明
  13. 基于HostLink协议的Fins命令读写
  14. TXT生成PCD文件
  15. 一款轻量级的权限框架,轻松搞定项目权限
  16. HTML+CSS网页设计期末课程大作——体育排球(5页面)
  17. Cesium 水淹分析
  18. 沙漠 草原 湖泊 羊群 骆驼(1)
  19. IDA Pro7.0使用技巧总结
  20. 图解 SQL 基础知识

热门文章

  1. 野生前端的数据结构基础练习(2)——队列
  2. 如何获取目标软件的Docker镜像
  3. php一定要用phpstudy,用phpstudy有什么好处
  4. mysql dba命令_mysql DBA:mysqladmin常用命令总结
  5. Kafka和其他消息队列
  6. 2021-07-12 原来我用的是CPU,更改方法
  7. 如何读取tensorboard文件 展现可视化
  8. Chromedriver的安装
  9. 从零开始学Pytorch(十七)之目标检测基础
  10. 关于三星某些系列笔记本电脑无法安装Windows10的原因及解决办法