《Effect C++》学习------条款22:将成员变量声明为private

为什么不采用public成员变量

首先,语法一致性考虑,客户唯一能访问对象的方法就是通过成员函数,客户不必考虑是否该记住使用小括号()。

其次,使用函数可以让你对成员变量的处理有更精确的控制。如果成员变量是public,每个人都可以读写它,但是如果你也函数。取得或设定其值,你就可以实现“不准访问”、“只读访问”,以及”读写访问”甚至”唯写访问“:

class AccessLevels 
{ 
public: 
    int getReadOnlay() const {return readOnly;} 
    void setReadWrite(int value){readWrite = value;} 
    int getReadWrite()const {return readWrite;} 
    void setWriteOnly(int value){writeOnly = value;} 
protected: 
private: 
    int noAccess; 
    int readOnly; 
    int readWrite; 
    int writeOnly; 
};

如此细微的访问控制颇为必要,因为许多成员变量应该被隐藏起来。

最后,还有封装性。如果通过函数访问成员变量,日后可改以某个计算替换这个成员变量,客户不会知道class内部实现已经起了变化。
如下面的测速程序,汽车通过,其速度被计算并填入一个速度收集器内:

class SpeedDataCollection 
{ 
public: 
    void addValue(int speed); //添加一笔新数据 
    double averageSoFar() const; //返回平均速度 
protected: 
private: 
};

考虑averageSoFar。做法之一是在class内设计一个成员变量,记录至今以来所有速度的平均值。当averageSoFar被调用,只返回那个成员变量就好。

另一个做法是令averageSoFar每次被调用时,重新计算平均值,此函数有权力调取收集器内的每一笔速度值。

哪一种做法更好,在内存吃紧的机器上,第一种做法会增加SpeedDataCollection对象的占用空间,在频繁需要平均值的应用程序中,内存不是重点。

所以,成员变量隐藏在函数接口的背后,可以为“所有可能的实现”提供弹性。例如这可使得成员变量被读或被写时轻松通知其他对象、可以验证class的约束条件及函数的前提和事后状态、可以在多线程环境中执行同步控制。。。等等。

封装性非常重要。如果对客户隐藏成员变量(也就是)封装,保留了日后变更实现的权力。public意味着不封装,不封装意味着不可改变

特别是被广泛使用的classes而言,因为他们最能够从“改采用一个较佳实现版本”中获益。

protected成员变量就像public成员变量一样缺乏封装性:

成员变量的封装性与“成员变量的内容改变时所破坏的代码数量”成反比,假设一个public成员变量,我们取消了它。所有使用它的客户码都会被破坏,那是一个不可知的大量。所以public成员函数完全没有封装性。假设一个protected成员变量,我们取消了它,所有使用它的derived classes都会被破坏,往往也是一个不可知的大量。

最后总结一下:

  • [x] 切记将成员变量声明为private,这可赋予客户访问数据的一致性、可细微划分访问控制、允诺约束条件获得保证,并提供class作者以充分的实现弹性

  • [x] protected并不比public更具封装性

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值