《C++ Primer Plus》学习笔记 | 第10章 对象和类
发布日期:2021-07-25 15:44:20 浏览次数:14 分类:技术文章

本文共 4462 字,大约阅读时间需要 14 分钟。

第10章 对象和类

面向对象编程OOP特性:

  • 抽象
  • 封装和数据隐藏
  • 多态
  • 继承
  • 代码的可重用性

10.1 过程性编程和面向对象编程

采用过程性编程

  • 首先考虑遵循的步骤,然后考虑如何表示这些数据。

采用OOP:

  • 首先考虑数据,考虑如何表示数据,和考虑如何使用数据。
    (首先从用户的角度考虑对象——描述对象所需的数据以及描述用户与数据交互所需的操作。完成对接口的描述后,需要确定如何实现接口和数据存储。最后,使用新的设计方案创建出程序。)

用户与数据交互的方式有三种:

  • 初始化
  • 更新
  • 显示数据

这就是用户接口。

10.2 抽象和类

处理复杂性的方法之一是简化抽象

C++中,用户定义类型指的是实现抽象接口的类设计。

10.2.1 类型是什么

指定基本类型完成了三项工作:

  • 决定数据对象需要的内存数量
  • 决定如何解释内存中的位;
    (longfloat在内存中占用的位数相同,但将它们转换为数值的方法不同)。
  • 决定可使用数据对象执行的操作或方法
10.2.2 C++中的类

是一种将抽象转换为用户定义类型的C++工具,它将数据表示操纵数据的方法组合成一个整洁的包。

定义类,一般来说,类规范由两个部分组成:

  • 类声明:以数据成员的方式描述数据部分,以成员函数(被称为方法)的方式描述公有接口。
  • 类方法定义:类声明提供了类的蓝图,而方法定义则提供了细节。
什么是接口

接口是一个共享框架,供两个系统交互时使用;

对于类,我们说公共接口。在这里,公众public是使用类的程序,交互系统由类对象组成,而接口由编写类的人提供的方法组成。
要使用某个类,必须了解其公共接口;要编写类,必须创建其公共接口。

  • 类名首字母大写。
  • 类就像一个结构声明,只是还包含成员函数,公有部分和私有部分等内容。
  • 类的变量成为对象或实例。
1. 访问控制

关键字privatepublicprotected也是新的,它们描述了对类成员的访问控制。

  • 使用类对象的程序都可以直接访问公有部分,但只能通过公有成员函数来访问对象的私有成员。
  • 公有成员函数是程序和对象的私有成员之间的桥梁,提供了对象和程序之间的接口。

防止程序直接访问数据被称为数据隐藏

封装的另一个例子是,将类函数定义和类声明放在不同的文件中。

2. 控制对成员的访问:公有还是私有

程序员使用私有成员函数来处理不属于公有接口的实现细节。

不必在类声明中使用关键字private,因为这是类对象的默认访问控制;

类和结构

区别是:

  • 结构的默认访问类型是public
  • 而类为private

C++程序员通常使用类来实现类描述,而把结构限制为只表示纯粹的数据对象(常被称为普通老式数据(PODPlain Old Data)结构)。

10.2.3 实现类成员函数
  • 定义成员函数时,使用作用域解析运算符(::)来标识函数所属的类;
  • 类方法可以访问类的private组件。
1. 内联方法

其定义位于类声明中的函数都将自动成为内联函数。类声明常将短小的成员函数作为内联函数。

也可以在类声明之外定义成员函数,并使其成为内联函数。只需要在实现部分中定义函数时使用inline限定符即可。
内联函数的特殊规则要求在每个使用它们的文件中都对其进行定义。确保内联定义对多文件程序中的所有文件都可用的、最简便的方法是:将内联定义放在定义类的头文件中。

2. 方法使用哪个对象

调用成员函数时,它将使用被用来调用它的对象的数据成员。

所创建的每个新对象都有自己的存储空间,用于存储其内部变量和类成员;但同一个类的所有对象共享同一组类方法,即每种方法只有一个副本。
在这里插入图片描述

10.2.4 使用类
客户/服务器模型
  • 客户是使用类的程序
  • 类声明(包括类方法)构成了服务器
    客户只能通过以公有方式定义的接口使用服务器,这意味着客户(客户程序员)唯一的责任是了解该接口。服务器(服务器设计人员)的责任是确保服务器根据该接口可靠并准确地执行。服务器设计人员只能修改类设计的实现的细节,而不能修改接口。这样程序员独立地对客户和服务器进行改进,对服务器的修改不会因客户的行为造成意外的影响。
10.2.5 修改实现

将修改限定在实现文件中,以免影响程序的其他方面。

10.2.6 小结

指定类设计的第一步是提供类声明

类声明类似结构声明,可以包括数据成员和函数成员。

  • 声明有私有部分,在其中声明的成员只能通过成员函数进行访问;
  • 声明还具有公有部分,在其中声明的成员可被使用类对象的程序直接访问。

通常,数据成员被放在私有部分中,成员函数被放在公有部分中。

公有部分的内容构成了设计的抽象部分——公有接口
将数据封装到私有部分中可以保护数据的完整性,这被称为数据隐藏

10.3 类的构造函数和析构函数

  • 让使用类对象就像使用标准类型一样。
  • 一般来说,最好是在创建对象时对它进行初始化。
    C++提供了一个特殊的成员函数——类构造函数,专门用于构造新对象、将值赋给它们的数据成员。名称和类名相同。构造函数没有返回值。
10.3.1 声明和定义构造函数
  • 构造函数的原型位于类声明的公有部分。
  • 程序声明对象时,将自动调用构造函数。
  • 不能将类成员名称用作构造函数的参数名。
10.3.2 使用构造函数
  • 显示地调用构造函数
  • 隐式的调用构造函数
  • new一起使用

构造函数构造出对象之前,对象是不存在的。因此构造函数被用来创建对象,而不是通过对象来调用。

10.3.3 默认构造函数

默认构造函数是在未提供显示初始值时,用来创建对象的构造函数。

如果没有提供任何构造函数,则C++将自动提供默认构造函数。
默认构造函数没有参数,因为声明中不包含值。

定义默认构造函数的方式有两种:

  • 给已有构造函数的所有参数提供默认值。
  • 通过函数重载来定义另一个构造函数——一个没有参数的构造函数。

在设计类时,通常应提供对所有类成员做隐式初始化的默认构造函数。

10.3.4 析构函数

用构造函数创建对象后,程序负责跟踪该对象,直到其过期为止。对象过期时,程序将自动调用一个特殊的成员函数——析构函数。析构函数完成清理工作。

如果构造函数使用new来分配内存,则析构函数将使用delete来释放这些内存。
和构造函数一样,析构函数的名称也很特殊:在类名前加上
和构造函数一样,析构函数也可以没有返回值和声明类型
与构造函数不同的是,析构函数没有参数

  • 如果创建的是静态存储类对象,则其析构函数将在程序结束时自动被调用。
  • 如果创建的是自动存储类对象,则其析构函数将在程序执行完代码块时自动被调用。
  • 如果对象是通过new创建的,则它将驻留在栈内存或自由存储区中,当使用delete来释放内存时,其析构函数将自动被调用。

如果程序员没有提供析构函数,编译器将隐时地声明一个默认析构函数,并在发现导致对象被删除的代码后,提供默认析构函数的定义。

10.3.5 改进Stock类
1. 头文件
2. 实现文件
3. 客户文件
4. 程序说明
  • 由于自动变量被放入棧中,因此最后创建的对象将最先被删除,最先创建的对象将最后被删除。
5. C++11列表初始化
  • 可以用大括号初始化
6. const成员函数

const关键字放在函数的括号后面,以这种方式声明和定义的类函数被称为const成员函数

  • 就像应尽可能将const引用和指针用作函数形参一样,只要类方法不修改调用对象,就应将其声明为const

10.3.6 构造函数和析构函数的小结

构造函数是一种特殊的类成员函数。在创建对象时被调用。构造函数的名称和类名相同,但通过函数重载,可以创建多个同名的构造函数,条件是每个函数的特征标(参数列表)都不同。另外,构造函数没有声明类型。通常,构造函数用于初始化类对象的成员,初始化应与构造函数的参数列表匹配。

在这里插入图片描述
⚠️接受一个参数的构造函数允许使用赋值语法将对象初始化为一个值。

  • 默认构造函数没有参数,因此如果创建对象时没有进行显式地初始化,则将调用默认构造函数。
  • 如果程序中没有提供任何构造函数,则编译器会为程序定义一个默认构造函数;否则,必须自己提供默认构造函数。
  • 默认构造函数可以没有任何参数;如果有,则必须给所有参数都提供默认值。
  • 就像对像被创建时程序将调用构造函数一样,当对象被删除时,程序将调用析构函数。
  • 每个类都只能有一个析构函数,析构函数没有返回类型,也没有参数,其名称为类名称前加上
  • 如果构造函数使用了new,则必须提供使用delete的析构函数。

10.4 this指针

类成员函数涉及到两个对象,在这种情况下需要使用C++this指针。

在这里插入图片描述
使用被称为this的特殊指针。this指针指向用来调用成员函数的对象(this被作为隐藏参数传递给方法)。一般来说,所有的类方法都将this指针设置为调用它的对象的地址。

  • 使用->运算符,通过指针来访问结构成员,这也适用于类成员。
注意:

每个成员函数(包括构造函数和析构函数)都有一个this指针。this指针指向调用对象。如果方法需要引用整个调用对象,则可以使用表达式*this。在函数的括号后面使用const限定符将this限定为const,这样将不能使用this来修改对象的值。

在这里插入图片描述

10.5 对象数组

在这里插入图片描述

要创建类对象数组,则这个类必须有默认构造函数。

10.6 类作用域

在类中定义的名称的作用域都为整个类,作用域为整个类的名称只在该类中是已知的,在类外是不可知的。因此,可以在不同类中使用相同的类成员名而不会引起冲突。

10.6.1 作用域为类的常量

在这里插入图片描述

10.6.2 作用域内枚举

在这里插入图片描述

10.7 抽象数据类型ADT

ADT以通用的方式描述数据类型,而没有引入语言或实现细节。

10.8 总结

设计一个类来实现接口

  • 私有数据成员存储信息
  • 公有成员函数提供访问数据的唯一途径。

类将数据和方法组合成一个单元,其私有性实现数据隐藏

通常,将类声明分为两部分组成,这两部分通常保存在不同的文件中。

  • 类声明应放到头文件中。
  • 定义成员函数的源代码放在方法文件中。

这样便将接口描述与实现细节分开了。从理论上说,只需知道公有接口就可以使用类。

是用户定义的类型,对象是类的实例。这意味着对象是这种类型的变量。
可以声明对象、指向对象的指针和对象数组。可以按值传递对象、将对象作为函数返回值、将一个对象赋给同类型的另一个对象。

  • 如果提供了构造函数,则在创建对象时,可以初始化对象。
  • 如果提供了析构函数方法,则在对象消亡后,程序将执行该函数。
    每个对象都存储自己的数据,而共享类方法。
  • 如果希望成员函数对多个对象进行操作,可以将额外的对象作为参数传递给它。如果方法需要显式地引用调用它的对象,则可以使用this指针。由于this指针被设置为调用对象的地址,因此*this是该对象的别名。
    类很适合用于描述ADT。公有成员函数接口提供了ADT描述的服务,类的私有部分和类方法的代码提供了实现,这些实现对类的客户隐藏。

转载地址:https://blog.csdn.net/qq_34170700/article/details/104339845 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:《SQL必知必会》| 第20课 管理事务处理 学习笔记
下一篇:学习笔记 | Ch19 存储过程

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年03月29日 08时51分44秒