【C++学习记录】第八章 类和对象的特性

本文详细阐述了C++中类与对象的概念及其关系,包括类的声明、对象的定义方法,成员函数的性质及存储方式等内容,并介绍了类的封装性和信息隐蔽特性。

8.2 类的声明和对象的定义

8.2.1 类和对象的关系

这里介绍了类和对象的关系 对于一个初学c++的人来说 了解类是什么 对象是什么 以及他们之间的关系是很重要的

c++中对象的类型称为类  类是对象的抽象 而对象是类的具体实例

 这个可以拿结构体来理解  结构体和类是十分相似的 只是结构体中只有数据成员  而类中除了数据成员 还有对这些数据成员进行操作的函数   那么 在学习结构体时  是先声明一个结构体类型  然后用它去定义结构体变量  同一个结构体类型可以定义出多个不同的结构体变量   类也是相同的道理   在c++中先声明一个类类型 再用它去定义出若干个同类型的对象 对象就是类类型的一个变量           

类是抽象的  不占用内存 而对象是具体的  占用存储空间 

8.2.2 声明类类型

在8.2.1中 说了 要想定义出一个对象 要先声明一个类类型 类类型就好比图纸 而对象就是根据图纸建造出的实物 那么如何声明一个类类型呢?

声明类类型和声明结构体类型是很相似的 

 上图为声明的一个结构体类型  结构体类型名为Stu  s1 s2为创建出的结构体变量  这里面只有数据 没有操作(函数)

下面演示如何声明一个类 并创建对应的对象 可以对照结构体 看看两者的差异                   

 第一行 class Student 为类头 由关键字class 和类名Student组成  class 类似于struct一样  是声明类是不可缺少的一部分

从第二行开始的花括号{}内的是类体  类的声明以分号结束

在类体中的是类的成员表 列出全部成员 有数据成员 还有对这些数据操作的函数 称为成员函数        这就体现了把数据和操作封装在一起    display是个成员函数 用来对本对象中的数据进行操作 作用是输出本对象中学生的姓名 学号 性别等相关信息 

现在 封装在类对象s1 s2中的成员都对外界隐蔽 外界不能调用他们 只有本对象中的函数display函数可以调用对象中的数据成员  但是 这样的设定之下 display函数外界也是不可以调用的  显然这样的类产生的对象是毫无意义的 因为外界不能调用类中的任何成员  因此 不能把类中的全部成员与外界隔离  一般是把数据隐蔽起来 而把成员函数作为外界的接口   于是就有了下面的类声明

 可以看到 这个类声明和前面的类声明最显著的差别就是 多了private 和 public 

一般的结构为:

private public 称为 成员访问限定符 用他们来声明各成员的访问属性 

被声明为私有的成员 只能被本类中的成员函数引用 类外不能调用。 被声明为公有的成员 既可以被本类中的成员函数所引用 也可以被类的作用域内的其他函数所引用 

 成员访问限定符 即指定了类成员的访问权限  被设定为私有的 外界就不可以访问了 这样就体现了c++中数据隔离的思想 这个思想是很关键的 有关这个思想 在学习c++过程中会逐渐明显与清晰

其实上方的很多概念都可以认真阅读领会一下 比如公有的成员的访问权限 即 不仅限于类中的成员函数所引用  还可以被类的作用域内的其他函数所引用

如果在类的定义中既不指定private ,也不指定 public,则系统就默认为是私有的(第1次的类声明就属此情况)。

在声明类类型时 private 和 public顺序任意 可多次重复使用 但是应该养成一个好习惯:private和public只出现一次  且建议在多数c++程序中 先出现public 后出现private 即先定义公有的数据成员  后定义私有的数据成员 把private放在类体的后部      这样可以让用户将注意力集中在能被外界调用的成员上 使阅读者的思路清晰一些

由于c++中要经常用到类 为了用户方便 c++编译系统往往向用户提供类库(但不属于c++语言的组成部分)内装经常用到的类 供用户使用 --  这就像库函数一样

8.2.3 定义对象的方法

定义对象是什么  比如前面的student类  通过已声明的student类定义对象s1  s2通过定义后 对象s1 s2 就成为了具有student类特征的对象 这两个对象都分别包括以上的数据和函数 

四种方法  12差不多 只是可以不写class  34差不多  不是很推荐  

总结 : 在有class Student  {...}; 类声明之后  定义对象时  直接写Student s1; 即可 s1 就是具有Student类特征的对象  (在定义一个对象时 编译系统会为这个对象分配存储空间,以存放对象中的成员)

8.3  类的成员函数

8.3.1 成员函数的性质

成员函数  归根结底还是函数的一种  与普通的函数有共同之处 即都有返回值 参数等  不同之处就是它是一种成员函数  成员 -- 即它是属于一个类的成员 出现在类体中 它可以被指定为private(私有的)public(公有的)或protected(受保护的)

使用成员函数时 要注意调用它的权限(它能否被调用)以及它的作用域(函数能使用什么范围内的数据和函数)  例如 私有的成员函数只能被本类中其他的成员函数所调用 而不能被类外调用     且一切成员函数(私有的或公用的)都可以访问本类对象中的任何成员(私有或公用)也可以引用本作用域中有效的数据

一般的做法是把需要被外界调用的成员函数指定为public  它们是类的对外接口  但注意并不是把所有的成员函数都指定为public 有的函数的作用就是辅助本类中的其他函数 可以指定为private 它是类中其他成员的工具函数

8.3.2 在类外定义成员函数

可以在类体中只对成员函数声明 而在类的外面对成员函数定义

注意 在类外定义成员函数时  需要在函数名前加上类名 予以限定  "::" 是作用域限定符 或 作用域运算符 用它声明函数是属于哪一个类的   这个是很有必要的...  可以设想不加之后会怎样 

类函数必须先在类体中做原型声明,然后在类外定义。 即类体的位置应在函数定义之前 否则编译时会出错

一般建议在类体内做函数声明 在类外定义函数  这样有利于使类的接口和类的实现细节分离

8.3.3 内置成员函数

如果在类体中定义的成员函数中不包括循环等控制结构 c++系统自动地把它们当做内置函数来处理 也就是说 调用这些函数时 并不是真正地执行函数的调用过程(如保留返回地址等处理)而是把函数代码嵌入到程序的调用点 这样可以大大减少调用成员函数的时间开销

c++要求对一般的内置函数要用关键字inline声明 但对类内定义的成员函数 可以省略inline 但如果成员函数在类体外定义 则需要对函数做显式的inline声明 (声明或定义时 开头加上inline  有其一即可) 但值得注意的是  如果在类外定义inline函数 则必须把类定义和成员函数的定义放在同一个头文件中  (或者写在同一个源文件中)否则编译时无法进行置换 但是这样做不利于类的接口和类的实现分离 不利于信息隐蔽 需要衡量 (只有在类外定义的成员函数规模很小而调用频率较高时 才指定为内置成员函数)
 

8.3.4 成员函数的存储方式

同一类的不同对象中的数据成员的值一般是不相同的,而不同对象的函数的代码是相同的,不论调用哪一个对象的函数的代码,其实调用的都是同样内容的代码。

每个对象所占的存储空间只是该对象的数据成员所占用的存储空间 而不包括函数代码所占用的存储空间   可以用sizeof函数计算对象所占的存储空间从而进行验证   函数的目标代码是存储在对象空间之外的 

如果一个类定义了十个对象 这些对象的成员函数对应的是同一个函数代码段 而不是10个不同的函数代码段   

那么这些不同对象使用的是同一段函数代码段 这个函数怎么区分去引用哪一个对象的数据呢? 这时 c++为此专门设定了一个this指针 用于指向不同的对象 (后面会有详细介绍)

注意 成员函数的代码段的存储方式永远都不占用对象的存储空间 永远都是存储在对象空间之外的   这与是否在类内定义成员函数  是否指定为inlineI(内置函数)是没有关系的 inline只会影响程序的执行效率 

8.4  对象成员的引用

在程序中经常需要访问对象中的成员。访问对象中的成员可以有3种方法:·

1.  通过对象名和成员运算符访问对象中的成员;
2.  通过指向对象的指针访问对象中的成员                                                                                3.  通过对象的引用访问对象中的成员。
 

1.  通过对象名和成员运算符访问对象中的成员

没什么好说的  注意用对象名访问和成员运算符访问对象中成员时  必须加上对象名就好了  如

 其中的  .  是成员运算符 是用来告诉编译器下面的数据是属于哪一个对象的 这个是必须的 否则就成了普通的变量了    还有要注意对象成员的访问权限  在类外只能访问public的数据成员或成员函数

2.  通过指向对象的指针访问对象中的成员

 77 78 79   都一样 这和结构体指针是一个道理  p指向s1时  (*p)=s1    

3.  通过对象的引用访问对象的成员 

 这个和普通的引用一样   其实就是给对象起了一个别名 这两个名字的使用是一模一样的  使用的是同一段存储空间 

 8.5  类的封装性和信息隐蔽

8.5.1  公用接口与私有实现的分离

公用成员函数是用户使用类的公用接口,或者说是类的对外接口  因为外界只有通过公用成员函数来实现对类中的私有数据的操作 所以称为类的对外接口

类中被操作的数据是私有的,类的功能的实现细节对用户是隐蔽的,这种实现被称为私有实现 

这种类的公用接口和私有实现的分离  形成了信息隐蔽

8.5.2 类声明和成员函数定义的分离

简单来说 就是类的声明放在一个头文件中  类的成员函数定义放在另一个源文件中  得到分离  当某一个源文件内要使用某个类时  用#include""  包含这个头文件就可以了 这样做好处是很多的

补充  其实针对8.5   这一章内容还是很多很重要的我认为 但是种种原因 导致我现在不想写了   所以 就此结束吧

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值