Effective C++ 2e Item20

原创 2001年07月11日 20:30:00

条款20: 避免public接口出现数据成员

首先,从“一致性”的角度来看这个问题。如果public接口里都是函数,用户每次访问类的成员时就用不着抓脑袋去想:是该用括号还是不该用括号呢?——用括号就是了!因为每个成员都是函数。一生中,这可以避免你多少次抓脑袋啊!

你不买“一致性”的帐?那你总得承认采用函数可以更精确地控制数据成员的访问权这一事实吧?如果使数据成员为public,每个人都可以对它读写;如果用函数来获取或设定它的值,就可以实现禁止访问、只读访问和读写访问等多种控制。甚至,如果你愿意,还可以实现只写访问:

class AccessLevels {
public:
  int getReadOnly() const{ return readOnly; }

  void setReadWrite(int value) { readWrite = value; }
  int getReadWrite() const { return readWrite; }

  void setWriteOnly(int value) { writeOnly = value; }

private:
  int noAccess;             // 禁止访问这个int

  int readOnly;             // 可以只读这个int

  int readWrite;            // 可以读/写这个int

  int writeOnly;            // 可以只写这个int
};

还没说服你?那只得搬出这门重型大炮:功能分离(functional abstraction)。如果用函数来实现对数据成员的访问,以后就有可能用一段计算来取代这个数据成员,而使用这个类的用户却一无所知。

例如,假设写一个用自动化仪器检测汽车行驶速度的应用程序。每辆车行驶过来时,计算出的速度值添加到一个集中了当前所有的汽车速度数据的集合里:

class SpeedDataCollection {
public:
  void addValue(int speed);       // 添加新速度值

  double averageSoFar() const;    // 返回平均速度
};

现在考虑怎么实现成员函数averageSoFar(另见条款M18)。一种方法是用类的一个数据成员来保存当前收集到的所有速度数据的运行平均值。只要averageSoFar被调用,就返回这个数据成员的值。另一个不同的方法则是在averageSoFar每次被调用时才通过检查集合中的所有的数据值计算出结果。(关于这两个方法的更全面的讨论参见条款M17和M18。)

第一种方法——保持一个运行值——使得每个SpeedDataCollection对象更大,因为必须为保存运行值的数据成员分配空间。但averageSoFar实现起来很高效:它可以是一个仅用返回数据成员值的内联函数(见条款33)。相反,每次调用时都要计算平均值的方案则使得averageSoFar运行更慢,但每个SpeedDataCollection对象会更小。

谁能说哪个方法更好?在内存很紧张的机器里,或在不是频繁需要平均值的应用程序里,每次计算平均值是个好方案。在频繁需要平均值的应用程序里,速度是最根本的,内存不是主要问题,保持一个运行值的方法更可取。重要之处在于,用成员函数来访问平均值,就可以使用任何一种方法,它具有极大价值的灵活性,这是那个在public接口里包含平均值数据成员的方案所不具有的。

所以,结论是,在public接口里放上数据成员无异于自找麻烦,所以要把数据成员安全地隐藏在与功能分离的高墙后。如果现在就开始这么做,那我们就可以无需任何代价地换来一致性和精确的访问控制。

编写高质量的iOS代码--Effective Objective-C 2.0 读书笔记

编写高质量的iOS代码--Effective Objective-C 2.0 读书笔记 这本书年初刷完,感觉不错,介绍了很多小点,都是平日不怎么关注的. 第1章 熟悉Objective-C...
  • uxyheaven
  • uxyheaven
  • 2014年12月26日 23:56
  • 5027

读书笔记_Effective C++_习惯C++

这是一本非常经典C++书籍,也是我在工作中发现自己C++上还有很多薄弱点的时候经常拿来充电的。这本书内容很多,讲了很多如何高效地使用C++的方法,有些地方自己也没能啃透,读过一遍后很多知识点容易忘记,...
  • John_cdy
  • John_cdy
  • 2015年05月04日 09:51
  • 2151

《Effective C++》:条款44-条款45

条款44将与参数无关的代码抽离templates 条款45运用成员函数模板接受所有兼容类型...
  • KangRoger
  • KangRoger
  • 2015年03月12日 22:01
  • 1475

Item 20:传递常量引用比传值更好 Effective C++笔记

Item 20: Prefer pass-by-reference-to-const to pass-by-value C++函数的参数和返回值默认采用传值的方式,这一特性是继承自C语言的。...
  • yangjvn
  • yangjvn
  • 2015年09月01日 12:08
  • 950

Effective C++之Item 20: 用 pass-by-reference-to-const(传引用给 const)取代 pass-by-value(传值)

1.引用传递提高执行效率; 2.避免切断问题; 缺省情况下,C++ 以传值方式将对象传入或传出函数(这是一个从 C 继承来的特性)。除非你特别指定其它方式,否则函数的参数就会以实际参数(a...
  • janeqi1987
  • janeqi1987
  • 2017年07月25日 15:03
  • 104

Effective Modern C++ Item 2

如果你已经读过条款1关于模板类型的推导,你几乎已经知道所有关于auto类型推导的知识了,因为除了一种特殊情况,auto类型推导就是模板类型推导。但怎么会这样?模板类型推导涉及模板和函数还有参数,但au...
  • Love_3_9
  • Love_3_9
  • 2017年08月03日 19:55
  • 183

Effective C++----3rd Edition, Item 2:用consts,enums和inlines取代#define

Item 2: 用 consts, enums 和 inlines 取代 #defines 作者:Scott Meyers 译者:fatalerror99 (iTePub's Nirvana) ...
  • qianqin_2014
  • qianqin_2014
  • 2016年05月10日 21:25
  • 214

effective C++ (Item2) Prefer <iostream> to <stdio.h>

type safety and extensibility are cornerstones of the C++ way of life.  int i; Rational r; cin >>...
  • yqdm_zju
  • yqdm_zju
  • 2011年11月03日 23:52
  • 630

Effective C++ (3rd Ed) 读书笔记(一)Item 2: Prefer constS, enumS, and inlineS to #defineS

#includecxvxv
  • persimmon2010
  • persimmon2010
  • 2013年11月27日 11:59
  • 304

Effective Modern C++:Item 2 ->弄清auto类型推断

弄清auto类型推断如果你已经读了Item 1关于模板类型推断的内容,你现在差不多已经知道了关于auto类型推断的所有知识,因为,除了有一个比较奇怪的例外,auto类型推断就是模板类型推断。但是这又是...
  • victorydh123
  • victorydh123
  • 2017年06月19日 11:57
  • 98
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Effective C++ 2e Item20
举报原因:
原因补充:

(最多只允许输入30个字)