访问函数
本节阅读量:在上一课中,讨论了public和private访问级别。作为提醒,类通常将其数据成员设置为私有,而私有成员不能由公共直接访问。
考虑以下Date类:
|
|
虽然该类提供了一个 print() 成员函数来打印Date,但这可能不足以满足用户的需要。例如,如果date对象的用户想要获得年份,该怎么办?或者将年份更改为不同的值?他们将无法这样做,因为m_year是私有的(因此不能被公共直接访问)。
对于某些类,(在类所处上下文中)需要适当地获取或设置私有成员变量的值。
访问函数
访问函数是一个普通的公共成员函数,其任务是检索或更改私有成员变量的值。
访问函数有两种:getter和setter。Getter(有时也称为访问器)是返回私有成员变量值的public成员函数。Setter(有时也称为mutator)是设置私有成员变量值的public成员函数。
Getter通常被设置为const,因此可以在常量和非常量对象上调用它们。Setter应该是非const,因此它们需要修改数据成员。
为了便于说明,更新Date类,以拥有一整套getter和setter:
|
|
这将打印:
|
|
访问函数命名
访问函数没有通用命名约定。当然,有一些命名约定比其他约定更受欢迎。
- 前缀为“get”和“set”:
|
|
使用“get”和“set”前缀的优点是,它清楚地表明,这些是访问函数(并且调用成本应该较低)。
- 没有前缀:
|
|
这种风格更简洁,并且对getter和setter使用相同的名称(依赖于函数重载来区分两者)。C++标准库使用此约定。
无前缀约定的缺点是,这样设置day成员的值并不特别明显:
|
|
- 仅限“set”前缀:
|
|
选择上面哪一个是个人偏好的问题。然而,强烈建议对setter使用“set”前缀。Getter可以使用“get”前缀,也可以不使用前缀。
关键点
在私有数据成员前面加上“m_”的最好原因之一是避免数据成员和getter具有相同的名称(C++不支持这一点,尽管Java等其他语言支持)。
提示
在setter上使用“set”前缀,使它们改变对象的状态的语义更加明显。
Getter应通过值或常量值引用返回
Getter应提供对数据的“只读”访问。因此,最佳实践是,它们应该通过值(如果制作成员的副本成本不高)或常量值引用(如果制作该成员的副本的成本很高)返回。
由于通过引用返回数据成员是一个非常重要的主题,因此将在后面更详细地讨论该主题。
访问函数的问题
关于应该使用或避免访问函数的情况,有相当多的讨论。许多开发人员会认为,访问函数的使用违反了良好的类设计(这是一个很容易填满整本书的主题)。
现在,我们将推荐一种务实的方法。创建类时,请考虑以下事项:
- 如果您的类没有不变量约束,并且需要大量访问函数,请考虑使用结构体(其数据成员是公共的),提供对成员的直接访问。
- 优先实现行为或操作,而不是访问函数。例如,不是实现setAlive(bool)这样的setter,而是实现kill() 和 revive() 函数。
- 仅在public区域需要合理获取或设置单个成员的值的情况下提供访问函数。
如果要为数据提供public访问函数,为什么要将其私有化?
这是一个很好的问题。将在后续讲解数据隐藏(封装)的好处时进行讲解。
