15.x — 第 15 章总结和测验

章节回顾

在每个(非静态)成员函数内部,关键字 this 是一个 const 指针,它保存当前隐式对象的地址。我们可以让函数通过引用返回 *this,以启用方法链,其中可以在一个表达式中对同一个对象调用多个成员函数。

最好将类定义放在与类同名的头文件中。简单成员函数(例如访问函数、空函数体的构造函数等)可以在类定义内部定义。

最好将非简单成员函数定义在与类同名的源文件中。

在类类型内部定义的类型称为嵌套类型(或成员类型)。类型别名也可以嵌套。

在类模板定义内部定义的成员函数可以使用类模板本身的模板参数。在类模板定义外部定义的成员函数必须重新提供模板参数声明,并且应该在(同一文件中)类模板定义下方定义。

静态成员变量是静态持续时间成员,由类的所有对象共享。即使没有实例化类的对象,静态成员也存在。最好使用类名、作用域解析运算符和成员名称来访问它们。

使静态成员 inline 允许它们在类定义内部初始化。

静态成员函数是可以不带对象调用的成员函数。它们没有 *this 指针,也无法访问非静态数据成员。

在类的主体内部,可以使用友元声明(使用 friend 关键字)来告诉编译器某些其他类或函数现在是友元。友元是一个类或函数(成员或非成员),被授予对另一个类的私有和保护成员的完全访问权限。友元函数是一个函数(成员或非成员),可以像类的成员一样访问类的私有和保护成员。友元类是一个可以访问另一个类的私有和保护成员的类。

小测验时间

问题 #1

让我们创建一个随机怪物生成器。这应该很有趣。

a) 首先,让我们创建一个名为 MonsterType 的怪物类型作用域枚举。包括以下怪物类型:龙、哥布林、食人魔、兽人、骷髅、巨魔、吸血鬼和僵尸。添加一个额外的 maxMonsterTypes 枚举器,这样我们就可以计算有多少个枚举器。

显示答案

b) 现在,让我们创建我们的 Monster 类。我们的 Monster 将有 4 个属性(成员变量):一个类型 (MonsterType)、一个名称 (std::string)、一个吼叫 (std::string) 和生命值 (int)。

显示答案

c) enum class MonsterTypeMonster 特有的,所以将 MonsterType 设为 Monster 内部的嵌套无作用域枚举,并将其重命名为 Type

显示答案

d) 创建一个构造函数,允许您初始化所有成员变量。

以下程序应编译通过

int main()
{
	Monster skeleton{ Monster::skeleton, "Bones", "*rattle*", 4 };

	return 0;
}

显示答案

e) 现在我们希望能够打印我们的怪物,以便验证它是否正确。编写两个函数:一个名为 getTypeString(),返回怪物类型作为字符串;另一个名为 print(),与下面示例程序的输出匹配。

以下程序应编译通过

int main()
{
	Monster skeleton{ Monster::skeleton, "Bones", "*rattle*", 4 };
	skeleton.print();

	Monster vampire{ Monster::vampire, "Nibblez", "*hiss*", 0 };
	vampire.print();

	return 0;
}

并打印

Bones the skeleton has 4 hit points and says *rattle*.
Nibblez the vampire is dead.

显示答案

f) 现在我们可以创建一个随机怪物生成器。让我们考虑一下我们的 MonsterGenerator 将如何工作。理想情况下,我们会要求它给我们一个 Monster,它会为我们创建一个随机怪物。因为 MonsterGenerator 没有状态,所以这是一个适合命名空间的候选对象。

创建 MonsterGenerator 命名空间。在其中创建名为 generate() 的函数。它应该返回一个 Monster。目前,让它返回 Monster{ Monster::skeleton, "Bones", "*rattle*", 4}

以下程序应编译通过

int main()
{
	Monster m{ MonsterGenerator::generate() };
	m.print();

	return 0;
}

并打印

Bones the skeleton has 4 hit points and says *rattle*

显示答案

g) 在 MonsterGenerator 命名空间中再添加两个函数。getName(int) 将接受一个介于 0 到 5 之间(包含)的数字,并返回您选择的名称。getRoar(int) 也将接受一个介于 0 到 5 之间(包含)的数字,并返回您选择的吼叫。此外,更新您的 generate() 函数以调用 getName(0)getRoar(0)

以下程序应编译通过

int main()
{
	Monster m{ MonsterGenerator::generate() };
	m.print();

	return 0;
}

并打印

Blarg the skeleton has 4 hit points and says *ROAR*

您的名称和声音将根据您的选择而变化。

显示答案

h) 现在我们将使生成的怪物随机化。从 8.15 -- 全局随机数 (Random.h) 获取“Random.h”代码并将其另存为 Random.h。然后使用 Random::get() 生成一个随机怪物类型、随机名称、随机吼叫和随机生命值(介于 1 到 100 之间)。

以下程序应编译通过

#include "Random.h"

int main()
{
	Monster m{ MonsterGenerator::generate() };
	m.print();

	return 0;
}

并打印类似以下内容:

Mort the zombie has 61 hit points and says *growl*

显示答案

guest
您的电子邮箱地址将不会被显示
发现错误?请在上方留言!
与勘误相关的评论在处理后将被删除,以帮助减少混乱。感谢您帮助使网站对每个人都更好!
来自 https://gravatar.com/ 的头像与您提供的电子邮箱地址相关联。
有回复时通知我:  
113 评论
最新
最早 最多投票
内联反馈
查看所有评论