欢迎光临散文网 会员登陆 & 注册

C++ 类的其他特性

2023-04-14 11:36 作者:S-a-i_  | 我要投稿

这一章我们将介绍类型成员、类的成员的类内初始值、可变数据成员、内联成员函数、从成员函数返回*this、如何定义并使用类类型及友元类。


类成员再探

为了展示这些新特性,我们需要定义一对相互关联的类,它们分别是Screen和window_mgr。


定义一个类型成员

screen表示显示器中的一个窗口,每个screen包含一个用于保存screen内容的string成员和三个size_type类型成员,分别用于表示光标的位置、屏幕的高和宽。


Screen类的成员函数

要是我们的类更加实用,还需要调价一个构造函数令用户能够自定义屏幕的尺寸和内容,以及其它两个成员,分别负责移动光标和读取给定位置的字符。

第二个构造器中为cursor成员隐式的使用了类内初始值,如果类中不存在cursor的类内初始值,我们就需要想其他成员一样显式的初始化cursor。

这里我们可以看出成员函数也可以被重载。


令成员作为内联函数

定义在类内部的成员函数是自动inline的,因此Screen的构造函数和返回光标所指字符的get函数默认是inline函数。

我们也可以在类的外部使用inline修饰函数定义

注意:inline成员函数也应该与相应的类定义在同一个头文件中。


可变数据成员

我们可以在变量声明时加入mutable关键字,这样即使这个变量处于const成员函数内,我们依旧可以修改他。

尽管some_member是一个const成员函数,他依然可以改变access_ctr的值,该成员是个可变成员,因此任何成员函数包括const函数在内都能改变他的值。


类数据成员的初始值

我们继续定义一个窗口管理类来表示显示器的一组Screen,这个类将包含一个Screen类型的vector,每个元素表示一个特定的Screen。默认情况下,我们希望Window_mgr类开始时总是拥有一个默认初始化的Screen。在C++11标准中,最好的方式就是把这个默认值声明成一个类内初始值

当我们初始化类的成员时,需要为构造函数传递一个符合成员类型的实参,上面我们使用一个单独的元素值对vector成员执行了列表初始化,这个Screen的值被传给vector<Screen>的构造函数。

注意:当我们提供一个类内初始值时,必须以符号=或花括号表示。



返回*this的成员函数

接下来我们添加一些函数,他们负责设置光标所在位置的字符或者其他任意给定位置的字符。

我们使用set成员的返回值是set的对象的引用,返回引用的函数是左值,意味着这些函数返回的是对象本身而不是副本。

的所有操作都执行在同一个对象上,等价于

如果我们令move和set的返回值是Screen而不是引用,等价于


从const成员函数返回this

我们继续添加一个名为display的操作,他打印Screen的内容,它类似于move和set,display函数也能返回执行对象的引用。

逻辑上我们只是打印这个对象,并不需要改变,所以我们令display为一个const成员,此时this指针将是指向const的指针,*this对象是const对象,所以display的返回类型应该是const Sales_data&,这样我们就不能把进行改变值的操作


基于const的重载

因为非常量版本的函数对于常量对象是不可用的,所以我们只能在一个常量对象上调用const成员函数,另一方面,虽然可以在非常量对象上调用常量版本或非常量版本,但是显然此时非常量版本是一个更好的匹配

当一个成员调用另一个成员时,this指针在其中隐式的传递,因此当display调用do_display时,他的this指针隐式的传递给do_display,而当display的非常量版本调用do_display时,他的this指针将隐式的从指向非常量的指针转换为常量指针。

do_display完成后,都会返回调用对象。


类类型

每个类定义了唯一的类型,即使他们的成员完全一样,这两个类也是不同类型。

对于一个类来说他的成员和其他任何类的成员都不是一回事。


类的声明

我们可以仅声明类而暂时不定义,这种声明有时候称为前向声明,在他声明之后定义之前是一个不完全类型,也就是说我们只知道他是一个类,却不明白他包含那些成员。

对于一个类,我们创建它的对象前他必须被定义,否则编译器无法了解这样的对象需要多少空间。

后面我们会讲述一种例外,直到被定义后数据成员才能被声明成这种类型。


友元再探

类可以把其他类或者其他的类的成员函数定义为友元。

类之间的友元关系

如果我们的window_mgr类想访问他管理的Screen类的内部数据。这样我们可以把window_mgr定义为Screen的友元

这样window_mgr就能访问Screen的私有成员。

如果clear不是Screen的友元,上面代码无法通过编译,因为clear无法访问height、width和contents等成员。

注意:友元没有传递性,Window_mgr的友元不是Screen的友元。


令成员函数作为友元

当把一个成员函数作为友元时,必须声明是哪个类的成员函数

想要某个成员函数作为友元我们必须按照如下方式设计程序

1首先定义Window_mgr类,其中声明clear函数,但是不能定义,在clear使用Screen成员之前必须先声明Screen。

2接下来定义Screen,包括对clear的友元声明

3最后定义clear,此时他才可以使用Screen的成员。


友元声明和作用域

类和非成员函数的声明不是必须在他们的友元声明之前,当一个名字第一次出现在一个友元声明中时,我们隐式的假定改名字在当前作用域是可见的,然而友元本身不一定真的声明在当前作用域中。

甚至就算在类的内部定义该函数,我们也必须在类的外部提供声明,从而让函数可见。

友元声明的作用是影响访问权限的,他本身并不是声明。

C++ 类的其他特性的评论 (共 条)

分享到微博请遵守国家法律