- 内容提要
- 前言
- 第 1 章 预备知识
- 第 2 章 开始学习 C++
- 第 3 章 处理数据
- 第 4 章 复合类型
- 第 5 章 循环和关系表达式
- 第 6 章 分支语句和逻辑运算符
- 第 7 章 函数——C++的编程模块
- 第 8 章 函数探幽
- 第 9 章 内存模型和名称空间
- 第 10 章 对象和类
- 第 11 章 使用类
- 第 12 章 类和动态内存分配
- 第 13 章 类继承
- 第 14 章 C++中的代码重用
- 第 15 章 友元、异常和其他
- 第 16 章 string 类和标准模板库
- 第 17 章 输入、输出和文件
- 第 18 章 探讨 C++新标准
- 附录 A 计数系统
- 附录 B C++保留字
- 附录 C ASCII 字符集
- 附录 D 运算符优先级
- 附录 E 其他运算符
- 附录 F 模板类 string
- 附录 G 标准模板库方法和函数
- 附录 H 精选读物和网上资源
- 附录 I 转换为 ISO 标准 C++
- 附录 J 复习题答案
11.7 总结
本章介绍了定义和使用类的许多重要方面,其中的一些内容可能较难理解,但随着实践经验的不断增加,您将逐渐掌握它们。
一般来说,访问私有类成员的唯一方法是使用类方法。C++使用友元函数来避开这种限制。要让函数成为友元,需要在类声明中声明该函数,并在声明前加上关键字 friend。
C++扩展了对运算符的重载,允许自定义特殊的运算符函数,这种函数描述了特定的运算符与类之间的关系。运算符函数可以是类成员函数,也可以是友元函数(有一些运算符函数只能是类成员函数)。要调用运算符函数,可以直接调用该函数,也可以以通常的句法使用被重载的运算符。对于运算符 op,其运算符函数的格式如下:
argument-list 表示该运算符的操作数。如果运算符函数是类成员函数,则第一个操作数是调用对象,它不在 argument-list 中。例如,本章通过为 Vector 类定义 operator +( ) 成员函数重载了加法。如果 up、right 和 result 都是 Vector 对象,则可以使用下面的任何一条语句来调用矢量加法:
在第二条语句中,由于操作数 up 和 right 的类型都是 Vector,因此 C++将使用 Vector 的加法定义。
当运算符函数是成员函数时,则第一个操作数将是调用该函数的对象。例如,在前面的语句中,up 对象是调用函数的对象。定义运算符函数时,如果要使其第一个操作数不是类对象,则必须使用友元函数。这样就可以将操作数按所需的顺序传递给函数了。
最常见的运算符重载任务之一是定义<<运算符,使之可与 cout 一起使用,来显示对象的内容。要让 ostream 对象成为第一个操作数,需要将运算符函数定义为友元;要使重新定义的运算符能与其自身拼接,需要将返回类型声明为 ostream &。下面的通用格式能够满足这种要求:
然而,如果类包含这样的方法,它返回需要显示的数据成员的值,则可以使用这些方法,无需在 operator<<( ) 中直接访问这些成员。在这种情况下,函数不必(也不应当)是友元。
C++允许指定在类和基本类型之间进行转换的方式。首先,任何接受唯一一个参数的构造函数都可被用作转换函数,将类型与该参数相同的值转换为类。如果将类型与该参数相同的值赋给对象,则 C++将自动调用该构造函数。例如,假设有一个 String 类,它包含一个将 char *值作为其唯一参数的构造函数,那么如果 bean 是 String 对象,则可以使用下面的语句:
然而,如果在该构造函数的声明前加上了关键字 explicit,则该构造函数将只能用于显式转换:
要将类对象转换为其他类型,必须定义转换函数,指出如何进行这种转换。转换函数必须是成员函数。将类对象转换为 typeName 类型的转换函数的原型如下:
注意,转换函数没有返回类型、没有参数,但必须返回转换后的值(虽然没有声明返回类型)。例如,下面是将 Vector 转换为 double 类型的函数:
经验表明,最好不要依赖于这种隐式转换函数。
您可能已经注意到了,与简单的 C-风格结构相比,使用类时,必须更谨慎、更小心,但作为补偿,它们为我们完成的工作也更多。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论