Effective C++读书笔记20: 避免 public 接口出现数据成员

  • A+
所属分类:体育平台

Effective C++读书笔记20: 避免 public 接口出现数据成员

换句话说,类的数据成员尽量私有化,有什么好处呢?

一致性

如果 public 接口里都是函数,用户每次访问类的成员时,直接使用括号就是了!因为每个成员都是函数。

访问控制

每个数据都有两种属性,读与写。如果数据成员为 public,这样就无法对数据进行读保护或者写保护了。所以有了成员函数,对私有数据来说,1.不提供任何方法;2.只提供读方法;3.只提供写方法;4.提供读写方法;看如下的代码就知道了。

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
};

功能分离

如果用函数来实现对数据成员的访问,以后就有可能用一段计算来取代这个数据成员。


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

class SpeedDataCollection {
public:
  // 添加新速度值
 void addValue(int speed); 
  // 返回平均速度
 double averageSoFar() const; 
};

怎么实现averageSoFar?

第一种方法:定义一个数据成员来保存当前收集到的所有速度数据的运行平均值。

实现起来很高效:它可以是一个仅用返回数据成员值的内联函数。

double averageSoFar() const
{return average;}// 缺点是浪费内存

第二种方法:则是在averageSoFar 每次被调用时才通过检查集合中的所有的数据值计算出结果。

double averageSoFar() const
{//不需要定义一个成员变量,
  //动态计算得到平均值
  double average;
  average = 所有速度值加起来/速度值数量;
  return average;
}

比较这两种方法,第一种用空间换时间(浪费内存用来存储average),

第二种用时间换空间(由于要动态计算,时间损失,运行时效率低)。

那么问题来了,怎么选择?

在频繁需要平均值的应用程序里,速度是最根本的,

内存不是主要问题(PC上内存不是问题,嵌入式应用中可能内存紧张),

选择第一种。第二种方法还有一个缺点,没有做到数据与功能分离,计算方法与数据写在一起,当计算公式优化或改变后,需要修改此函数。第一种方法则做到了数据与功能分离,当计算平均值的公式改变后,用户无感知。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: