以下为个人学习笔记和习题整理
课程:计算机程序设计(C++)- 西安交通大学 @ 中国大学 MOOC
https://www.icourse163.org/course/XJTU-46006
# 课堂笔记
# 实体、对象与类的概念
# 实体
什么是实体?
是指客观世界存在的某个事物一所大学,例如:西安交通大学
某动物,例如:一只羊
一本图书,例如:《C++ 程序设计教程》
一篇文章,例如:“羊年趣赏羊联”如何描述实体?
通过对实体进行抽象,来描述实体如何抽象描述实体?
每个实体都有其特征和功能,特征和功能通称为属性
实体与实体的不同,在于属性的不同从实体中抽取出若干特征和功能,来表示实体
特征指实体的静态属性,功能指实体的动态属性
特征和功能密切相关、相互依赖,不能割裂
电视机的特征 | 电视机的功能 |
---|---|
型号 | 播放影视 |
尺寸 | 选频道 |
液晶 | 调颜色 |
价格 | 调音量 |
当然有些实体只有静态属性而无动态属性,如兵马俑等
# 对象
- 什么是对象?
指被抽象描述的某个实体
对象 = 实体的特征 + 实体的功能
对象 = 数据 + 函数
将数据和函数当作一个统一体
# 类
什么是类?
具有相同特征和功能的对象集合
对象是类的一个实例或个体或元素所有公元日期→日期类
所有西安交大学生→西安交大学生类
整数集合→整数类int k;//k 称为整数变量,又称整数对象
struct date today;//today 称日期结构体变量,又称日期对象
将实体转化为程序中的数据
C++ 程序中有四种基本数据类型:字符、整数、浮点、双精度类型
当程序中涉及到的实体不能直接描述为基本数据类型时,只有描述成新的数据 (类型)类是相同属性的对象集合,其中某个对象的特征和功能就是类的特征和功能
- 学生 (数据) 类 (型) 的特征和功能
特征:姓名、性别、年龄、学号、成绩、身高……
功能:上课、跑步、听、说、读、写、…… - 轿车 (数据) 类 (型) 的特征和功能
特征:型号、颜色、价格、出厂日期、轮子直径……
功能:运动、鸣笛、加油、倒车、……
- 学生 (数据) 类 (型) 的特征和功能
类与结构体
将数据和函数当作一个统一体,即 “类”
类是对客观世界万物的抽象描述
结构体是复合数据的统一体结构体只有数据成员,没有函数成员
结构体又称为特殊的类
现在结构体中也可以包括函数成员类的语法格式与结构体相似:
- 先定义类的数据成员和函数成员
- 再声明具体对象 (变量)
- 然后使用对象 (变量)
# 类的定义
# 定义格式
class <类名> | |
{ | |
private: // 私有成员 | |
<数据成员说明语句>; | |
<函数成员说明语句>; | |
public: // 公有成员 | |
<数据成员说明语句>; | |
<函数成员说明语句>; | |
protected: // 保护成员 | |
<数据成员说明语句>; | |
<函数成员说明语句>; | |
}; |
# 例子:定义实体钟表类
- 如何抽象描述
特征:即数据成员?
时、分、秒
型号、生产厂、出厂日期、价格等
功能:即函数成员?
设置时间
钟表运转或运行
报时响铃
显示时间
class Clock // 定义钟表类 | |
{ | |
private: // 数据成员一般为私有成员 | |
int Hour; // 小时属性 | |
int Minute; // 分钟属性 | |
int Second; // 秒属性 | |
float Price; // 价格属性 | |
public:// 函数成员一般为公有成员 | |
void Set(int h,int m,int s,float p); // 设置时间操作 | |
void Run(); // 钟表运转操作 | |
void Report_Time(); // 报时响铃操作 | |
void Show_Time(); // 显示时间操作 | |
}; |
# 成员函数的两种定义方法
# 内联函数
在类体内直接定义函数成员,该成员函数又称内联函数
在类体内定义内联函数等同一般函数定义格式
class Clock // 定义钟表类 | |
{ | |
private: // 数据成员一般为私有成员 | |
int Hour; // 小时属性 | |
int Minute; // 分钟属性 | |
int Second; // 秒属性 | |
float Price; // 价格属性 | |
public:// 函数成员一般为公有成员 | |
void Set(int h,int m,int s,float p); // 设置时间操作 | |
void Run(); // 钟表运转操作 | |
void Report_Time(); // 报时响铃操作 | |
void Show_Time() // 显示时间操作 | |
{ | |
cout<<Hour<<':'<<Minute<<':'<<Second; | |
}; | |
}; |
# 类体外定义函数成员
<类型> <类名>::<函数名>(<参数表>) | |
{ | |
<函数体> | |
} |
void Clock::Set(int h,int m,int s,float p) // 设置修改 4 个数据成员的值的函数 | |
{ | |
Hour = h; | |
Minute = m; | |
Second = s; | |
Price = p; | |
} | |
void Clock::Run() // 模拟运行钟表运行函数 | |
{ | |
int i=0; | |
for(i=0;i<10;i++) // 只模拟运行 10 秒钟 | |
{ | |
Second++; | |
if(Second==60) | |
{ | |
Second=0; | |
Minute++; | |
if(Minute==60) | |
{ | |
Minute=0; | |
Hour++; | |
if(Hour==24) { | |
Hour=0; | |
} | |
} | |
} | |
cout<<'\r'; // 不换行,返回当前行的首位 | |
Sleep(1000); // 程序暂停运行秒 | |
Show_Time(); | |
} | |
} | |
void Clock::Report_Time() { | |
Show_Time(); | |
if ( Minute==0&&Second==0 ) { | |
for(int i=0;i<Hour;i++) { | |
cout<<"\007"; | |
Sleep(1000); | |
} | |
} | |
} |
# 对象的声明与引用
# 对象的声明
用已定义的类去声明对象 (即变量),类似于结构体。
声明对象的一般形式 (类的实例化):
<类名> <对象1>, <对象2>, …… ; | |
// 如 | |
Clock XJTU_Big_Ben, Omega, Rossini; |
# 对象的引用
对象的引用类似于结构体
对类中成员的访问,采用 .
运算符
Rossini.Set(8,32,53,1000); | |
Rossini.Show_Time(); |
一般在类体外,只有公有成员可以采用
.
运算符访问
私有、保护成员都不能采用.
运算符访问
可以直接进行对象赋值
Omiga=Rossini; |
# 对象的存储空间
- 若一个类声明了五个对象,存储空间如何分配?
数据成员分配存储空间
是否对象中的数据和函数成员都占用存储空间?
函数成员共用一个存储空间
# 引用对象应该注意
- 成员函数直接访问同类中的数据成员 (公有和私有)
- 对象访问其数据成员或成员函数需使用运算符
.
- 禁止直接访问一个对象中的私有成员
- 同类对象之间可以整体赋值
- 对象用作函数的参数时属于赋值调用
- 对象可以用作函数值类型,函数可以返回一个对象
# 小结
- 公有成员:外界能够直接访问,起着接口的作用
- 私有成员:外界不能直接访问,使得成员被隐藏起来
- 一个实体的属性往往被定义为私有成员,方法被定义为公有成员
- 通过类中提供的函数对类中的数据进行操作,达到数据的安全性
- 类名、各成员名称要符合标识符规范
- 成员函数可在类中定义,也可在类外定义
- 各成员的访问权限应根据实际需要确定
- 书写顺序任意,有时 public 放在前边,有时写几个 public 或几个 private
- 类中的数据成员不能使用表达式进行初始化
# 公有、私有和保护成员
# 公有成员
在 public
后面定义的数据成员和函数成员都称作公有成员
public: | |
char name[10]; | |
int min(int a, int b); |
外界 (类外) 能够直接访问该成员,通过 .
运算符
一般函数成员被定义为公有成员
通过调用公有函数成员实施规定的操作
外界与类之间起着接口的作用
例如:钟表类中的设置函数 set(int,int,int,float)
就定义成公有成员。
class Clock | |
{ | |
public: | |
void set(int h,int m,int s,float p) | |
{ | |
// 对小时、分钟、秒钟的值进行有效性检验后,再赋值 | |
Hour=h>=0&&h<=24?h:0; | |
Minute=m>=0&&m<=60?m:0; | |
Second=s>=0&&s<=60?m:0; | |
Price=p; | |
} | |
}; // 分号别忘 | |
Clock XJTU; | |
XJTU.set(11,23,25,1000); // 正确 |
# 私有成员
在 private
后面定义的数据成员和函数成员都称作私有成员
private: | |
int age; | |
int max(int a, int b); |
外界 (类外) 不能够直接访问该成员
一般数据成员被定义为私有成员
使得成员被封装隐藏起来,外界不能随便修改对象的私有数据成员
只有通过类中公有函数对数据进行修改,达到数据的安全性
例如:钟表类的时分秒定义为私有成员,通过 set()
函数才能修改。
class Clock | |
{ | |
private: | |
int Hour,Minute,Second; | |
float Price; | |
public: | |
void set(int h,int m,int s,float p); | |
…… | |
}; | |
Clock XJTU; | |
XJTU.Hour=10; // × |
# 保护成员
在 protected
后面定义的数据成员和函数成员都称作保护成员
protected: | |
float price; | |
int abs(int a); |
外界部分区域能够访问该成员
换句话说某些数据或函数成员在类外被有限制的访问
私有是对外界完全封闭,公有是完全开放,保护是介于两者之间
例如:下面有两个类的定义,一个是时间类,一个是日期类
class time | |
{ | |
private: | |
int hour,minute; | |
protected: | |
int second; | |
…… | |
}; | |
class date:public time | |
{ | |
private: | |
int year,month,day; | |
public: | |
void show_date_time() | |
{ | |
cout<<year<<'-'<<month<<'-'<<day<<'\t'; | |
cout<<hour<<'-'<<minute<<'-'<<second<<endl; | |
//hour 报错 minute 报错 second 正确 | |
} | |
…… | |
}; |
# 两种程序设计思想
# 面向过程的程序设计 (Structured Programming)
以功能为中心,通过分解功能,采用函数来描述操作
数据与函数分离,数据(类型或结构)一旦发生改变,函数也要相应改变
例如排序函数: void sort(int a[],int n);
只能排序整数数组
# 面向对象程序设计 (Object Oriented Programming)
以数据为中心,采用对象来描述内部属性和操作方法
将数据和函数当作一个统一体,采用软件对象模拟客观世界中实际对象
例如:钟表类、日期类
特征:
抽象:实体特征 + 实体功能
如钟表、日期、分数等实体的抽象描述封装:数据和函数封装组成统一体
通过公有成员函数修改数据、显示数据、取得数据继承:将对象 (实体) 之间的差异通过继承性加以抽象描述
动物
→{人、大象、鸟…}
→{学生、工、农、兵…}
→{大学生、中学生…}
→…多态性:指相同语法结构(数据或操作)代表多种功能
如+
、-
、*
、/
优点:
- 开发时间短,效率高,可靠性高
- 重用,共享,可维护性,精简
- 适合于大型程序长时间的团队开发工作
- 为什么要引入数组?
太多的变量(全班同学的 C++ 成绩)- 为什么要引入函数?
结构化程序设计:功能分解,代码重用- 为什么要引入指针?
加快速度、参数传递、动态分配内存- 为什么要引入结构体?
复合数据结构,不同数据类型的聚合在一起- 为什么要引入类?
采用人们认识客观世界的自然方式去模拟客观世界中对象, 将客观世界中的实体完整性的描述(即数字化)
提高开发程序的效率和可靠性, 数据与代码的聚合(以便更高级的代码复用)
# 课堂讨论
- 如何采用类去声明一个对象数组?
<类名> <数组名>[数组长度] |
# 随堂练习
一个实体与另一个实体的不同,就在于 。
类是对象的集合。
具有相同特征和功能的对象的集合
在一个类的定义格式中, 。
在类的定义格式中,函数成员只能在类外定义。
在类的定义格式中,在类体末右
}
后面可以没有分号。在类外,通过。运算符可以访问一个对象中的 。
数据成员只能定义为私有,函数成员只能定义为公有。
面向对象程序设计方法 4 个特征为:抽象、封装、继承和多态。