C++ Primer 第五版 第七章 类

news/2024/10/22 12:28:37/

类的基本思想是数据抽象(data abstraction)和封装(encapsulation)。数据抽象是一种依赖于接口(interface)和实现(implementation)分离的编程(以及设计)技术。类的接口包括用户所能执行的操作;类的实现则包括类的数据成员、负责接口实现的函数体以及定义类所需的各种私有函数。

封装实现了类的接口也和实现的分离。封装后的类隐藏了它的实现细节,类的用户只能使用接口而无法访问实现部分。

作为一个设计良好的类,既要有直观且易于使用的接口,也必须具备高效的实现过程。

一、定义抽象数据类型

成员函数的声明必须在类的内部,它的定义可以在类的内部也可以在类的外部。定义在类内部的函数是隐式的inline函数。

 const成员函数

默认情况下,this的类型是指向类类型非常量版本的常量指针。

紧跟在参数列表后面的const表示this是一个指向常量的指针。像这样使用const的成员函数被称作常量成员函数(const member function)。

类本身就是一个作用域。类的成员函数的定义嵌套在类的作用域之内。

编译器分两步处理类:首先编译成员的声明,然后才轮到成员函数体(如果有的话)。因此,成员函数体可以随意使用类中的其他成员而无须在意这些成员出现的次序。

在类的外部定义成员函数

类外部定义的成员的名字必须包含它所属的类名:

IO类型属于不能被拷贝的类型,因此我们只能通过引用来传递它们。

1. 构造函数

类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数。构造函数的任务是初始化类对象的数据成员,无论何时只要类的对象被创建,就会执行构造函数。

构造函数的名字和类名相同。构造函数没有返回类型。

不同于其他成员函数,构造函数不能被声明成const的。

默认构造函数

类通过一个特殊的构造函数来控制默认初始化过程,这个函数叫做默认构造函数。默认构造函数无须任何实参。

如果我们的类没有显式地定义构造函数,那么编译器就会为我们隐式地定义一个默认构造函数。编译器创建的构造函数又被称为合成的默认构造函数(synthesized default constructor)。

一旦我们定义了一些其他的构造函数,那么除非我们再定义一个默认的构造函数,否则类将没有默认的构造函数。

构造函数初始值列表

构造函数的函数体是空的,因为构造函数的唯一目的就是为数据成员赋初值。

2. 拷贝、赋值和析构

很多需要动态内存的类能(而且应该)使用vector对象或者string对象管理必要的存储空间。使用vector或者string的类能避免分配和释放内存带来的复杂性。

二、访问控制与封装

使用访问说明符加强类的封装性:

一般来说,作为接口的一部分,构造函数和一部分成员函数应该定义在public说明符之后,而数据成员和作为实现部分的函数则应该跟在private说明符之后。

使用class或struct关键字:如果我们使用struct关键字,则定义再第一个访问说明符之前的成员是public的;相反,如果我们使用class关键字,则这些成员是private的。

1. 友元

友元声明只能出现在类定义的内部,最好在类定义开始或结束前的位置集中声明友元。

友元的声明仅仅只定了访问的权限,在友元声明之外再专门对函数进行一次声明。

为了使友元对类的用户可见,我们通常把友元的声明与类本身放置在同一个头文件中(类的外部)。

三、类的其他特性

用来定义类型的成员必须先定义再使用,这一点与普通成员有所区别,因此类型成员通常出现在类开始的地方。

1. 可变数据成员

在变量的声明中加入mutable关键字,使之成为可变数据成员。

一个可变数据成员永远不会是const,任何成员函数,包括const函数在内都能改变它的值。

2. 类内初始值

含有指针数据成员的类一般不宜使用默认的拷贝和赋值操作。

3.  返回*this的成员函数

3. 类类型

对于一个类来说,在我们创建它的对象之前该类必须被定义过,而不能仅仅被声明。

4. 友元再探

类还可以把其他的类定义成友元,也可以把其他类(之前已定义过的)成员函数定义成友元

(这样其他类就可以访问该类的私有成员)。此外,友元函数能定义在类的内部,这样的函数是隐式内联的。

四、类的作用域

一个类就是一个作用域,当我们在类的外部定义成员函数时必须同时提供类名和函数名。在类的外部,成员的名字被隐藏起来了。

1. 名字查找与类的作用域

类的定义分两步处理:

类型名要特殊处理

在类中,如果成员使用了外层作用域中的某个名字,而该名字代表一种类型,则类不能在之后重新定义改名字:

五、构造函数再探
1. 构造函数初始值列表

构造函数中对数据成员执行赋值操作,和列表初始化不同(初始化和赋值的差异)

构造函数初始值列表只说明用于初始化成员的值,而不限定初始化的具体执行顺序。

使用默认实参的构造函数:不提供实参也能调用这个构造函数,实际上为类提供了默认构造函数。

2. 委托构造函数

一个委托构造函数可以使用它所属类的其他构造函数执行它自己的初始化过程。

3. 隐式的类类型转换

只允许一步类型转换

抑制构造函数定义的隐式转换

explicit构造函数只能用于直接初始化

标准库中含有显式构造函数的类

4. 聚合类

聚合类(aggregate class)使得用户可以直接访问其成员,并且具有特殊的初始化语法形式。

当一个类满足如下条件时,我们说它是聚合的:

我们可以用一个花括号括起来的成员初始值列表初始化聚合类的数据成员,初始值的顺序必须与声明的顺序一致。

5. 字面值常量类

一个字面值常量类必须至少提供一个constexpr构造函数。

constexpr构造函数可以声明成=default的形式。否则,constexpr构造函数就必须既符合构造函数的要求(意味着不能包含返回语句),又符合constexpr函数的要求(意味着它能拥有的唯一可执行语句就是返回语句)。所以constexpr构造函数体一般来说应该是空的。我们通过前置关键字constexpr就可以声明一个constexpr构造函数了:

constexpr构造函数必须初始化所有数据成员。

六、类的静态成员
声明静态成员

在成员的声明之前加上关键字static使得其与类关联在一起。静态成员不是任意单独对象的组成部分,而是由该类的全体对象所共享。

静态成员作用域位于类的范围之内,避免与其他类的成员或者全局作用域的名字冲突;可以设私有成员。

定义静态成员

静态成员的类内初始化

静态成员独立于任何对象

我们可以使用静态成员作为默认实参。


http://www.ppmy.cn/news/1457776.html

相关文章

【Spark】 Spark核心概念、名词解释(五)

Spark核心概念 名词解释 1)ClusterManager:在Standalone(上述安装的模式,也就是依托于spark集群本身)模式中即为Master(主节点),控制整个集群,监控Worker。在YARN模式中为资源管理器ResourceManager(国内s…

【毕业设计】基于微信小程序的校园快递平台系统设计与实现

1.项目介绍 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统校园快递平台系统信息管理难度大,容错率…

嵌入式移植7Z解压缩(纯C)

本文分享一个纯C语言编写的7Z解压缩代码库,本代码库的主要目的是在嵌入式环境下使用7z解压缩文件,可以将升级包通过7z进行压缩,然后发送给设备,减小和设备传输过程中的文件大小,进而达到传输大文件的目的。 下载链接 …

短视频矩阵系统源码saas开发--可视化剪辑、矩阵托管、多功能合一开发

短视频矩阵系统源码saas开发(可视化剪辑、矩阵托管、智能私信聚合、线索转化、数据看板、seo关键词、子账号等多个板块开发) 短视频矩阵系统是一种集成了多种功能的系统,旨在帮助用户在短视频平台上进行高效的内容创作、管理和发布。根据您提…

vector介绍与使用【C++】

C vector 前言一、vector的介绍c文档介绍简介 二、vector的定义和使用vector的定义vector代码演示 vector的使用vector iterator 的使用vector 空间增长问题vector 增删查改vector 迭代器失效问题引起底层空间改变eraseg与vs检测比较string迭代器失效 vector 在OJ中的使用只出现…

SGP.22-V.3.1-安全2

有任何关于GSMA\IOT\eSIM\RSP\业务应用场景相关的问题,欢迎W: xiangcunge59 一起讨论, 共同进步 (加的时候请注明: 来自CSDN-iot). InitialiseSecureChannel 在 SGP.22 v3.1 技术规范的第 2.5.4.1 节 "Description of InitialiseSecureChannel Block"…

纯血鸿蒙APP实战开发——短视频切换实现案例

短视频切换实现案例 介绍 短视频切换在应用开发中是一种常见场景,上下滑动可以切换视频,十分方便。本模块基于Swiper组件和Video组件实现短视频切换功能。 效果图预览 使用说明 上下滑动可以切换视频。点击屏幕暂停视频,再次点击继续播放…

LeetCode 每日一题 ---- 【2079.给植物浇水】

LeetCode 每日一题 ---- 【2079.给植物浇水】 2079.给植物浇水方法:模拟-维护水的剩余量 2079.给植物浇水 方法:模拟-维护水的剩余量 模拟浇水和灌水的步骤就可以了,当剩余水大于等于需要浇的水,步数累加1即可,当剩余…