返回:贺老师课程教学链接
谈及运算,我们总是习惯“数”的运算。而实际上,像时间之类的对象也是可以进行加减运算的。再进一步,我们的思维还可以拓展,运算加以加到任何事物上,只要我们可以为这些“运算”设计好意义。
例如:有班级类和学生类。两个学生相加,组成了一个由两个学生构成的班级;班级加学生,代表班级增加了一名新同学;学生乘学生,结果为这两个学生“结对子”,可以做某些事(这个对子,需要定义成一个新的类);班级乘班级,是班级中的所有学生,两两结对子的所以可能组合。
实际上,班级和学生,已经初步具备了数据库中用“学生表”存储学生信息的特征。一张“学生表”代表一个班级,而这张表中的每一条“记录”,则是具体的学生对象。
利用数据库技术可以建立这张表格,可以用操纵数据库的语言(SQL语言),完成对数据的相关处理。
这些处理,建立在数据库理论基础上。对于关系型数据库(前述“学生表”,按术语讲,就是一个“关系”),其基础是“关系代数”。关系代数,实际上就是定义了一组运算。无论这些运算用什么样的符号,可以与C++中重载后的运算符建立起联系来,让我们一起体会一下,若用C++去实现数据库最底层的运算,将可以采取什么样的策略。
更深一层,代数系统就是由一个非空集合和一组运算构成的系统。这是任何计算模型(计算模型可以是通用的模型,更多我们强调的就是解决具体问题的计算模式),在本质上的描述。关系代数,只不过也就是代数系统中的一个例子罢了。
所以,有机会“科班”学习计算机的同学,随着课程的进展,借助离散数学(代数系统是这门课程中的一部分)、可计算性理论等,体会从最一般的、抽象的层面看待计算,这是形成专业思维的重要部分。
当然,在学习C++的时候,体会到“万物皆对象,各种操作皆运算”,摆脱运算一定是施加于“数”上的观念,可以有助于将未来要学习的抽象理论具体起来。大学的学习,达到理论联系实际很有必要。为此,本文的目标,就是让菜鸟在接触专业理论之前,至少隔着门缝看了一眼。
下面的代码来点干货,学生加学生的运算,可以这样实现:
#include <iostream> using namespace std; class Student; class Class //班级类 { int number; Student *students; friend class Student; public: Class(); Class(const Class &c); void display(); }; class Student //学僧类 { private: int num; string name; char sex; int age; friend class Class; public: Student(){} Student(int n, string nam, char s, int a); Class operator+(Student &s1); }; Class::Class():number(0),students(NULL) {} Class::Class(const Class &c) { number=c.number; students=new Student[number]; int i; for(i=0;i<number;i++) students[i]=c.students[i]; } void Class::display() { int i; for(i=0; i<number; i++) { cout<<i<<": "<<students[i].num<<", "<<students[i].name; cout<<", "<<students[i].sex<<", "<<students[i].age<<endl; } } Student::Student(int n, string nam, char s, int a):num(n), name(nam), sex(s),age(a) {} Class Student::operator+(Student &s1) { Class c; c.number=2; c.students=new Student[c.number]; c.students[0]=*this; c.students[1]=s1; return c; } int main() { Student s1(1, "Zhang", ‘f‘, 20), s2(2, "Li", ‘m‘, 18); Class c = s1+s2; c.display(); return 0; }
进一步的拓展(请感兴趣的读者作为实践题目):
定义了Student s1, s2; Class c1, c2; 后:
(1)你是否可以定义出支持c1+c2、c1+s1、c1-c2之类的运算?
(2)为s1*s2、s1*c1、c1*c2确定其含义,必要时增加新的类型定义,实现*运算符的重载?
(3)(更远的未来)参考关系代数中对除法的定义,实现c1/s1、c1/c2运算?