(一)为什么不采用public成员变量
(1)首先,从语法一致性考虑,客户唯一能访问对象的方法就是通过成员函数,客户不必考虑是否该记住使用小括号()。
(2)其次,使用函数可以让我们对成员变量的处理有更精确的控制。如果我们令成员变量为public,那么每个人都可以读写它!
但如果我们以函数取得或设定其值,我们就可以实现出“不准访问”、“只读访问”以及“读写访问”,我们甚至可以实现“惟写访问”。
class AccessLevels { public: //成员noAccess无任何访问动作,实现不准访问! int getReadOnlay() const {return readOnly;} //对这个数据成员设置为只读访问! void setReadWrite(int value){readWrite = value;} //这个函数设置该数据成员可写访问! int getReadWrite()const {return readWrite;} //这个函数设置该数据成员可读访问! void setWriteOnly(int value){writeOnly = value;} //这个函数设置该数据成员惟写访问! private: int noAccess; int readOnly; int readWrite; int writeOnly; };像这样细微地划分访问控制颇有必要,因为许多成员变量应该被隐藏起来。每个成员变量都需要一个getter函数和setter函数毕竟罕见。
(3)最后,还有封装性。如果通过函数访问成员变量,日后可改以某个计算替换这个成员变量,客户不会知道class内部实现已经起了变化。
成员变量隐藏在函数接口的背后,可以为“所有可能的实现”提供弹性。例如这可使得成员变量被读或被写时轻松通知其他对象、可以验证class的约束条件及函数的前提和事后状态、可以在多线程环境中执行同步控制。。。等等。
封装性非常重要。如果对客户隐藏成员变量(也就是)封装,保留了日后变更实现的权力。public意味着不封装,不封装意味着不可改变。
protected成员变量就像public成员变量一样缺乏封装性:成员变量的封装性与“成员变量的内容改变时所破坏的代码数量”成反比,假设一个public成员变量,我们取消了它。所有使用它的客户码都会被破坏,那是一个不可知的大量。所以public成员函数完全没有封装性。假设一个protected成员变量,我们取消了它,所有使用它的derived classes都会被破坏,往往也是一个不可知的大量。
请记住:
(1)切记将成员变量声明为private。这可赋予客户访问数据的一致性,可细微划分访问控制,允诺约束条件获得保证,并提供class作者以充分的实现弹性。
(2)protected并不比public更具封装性。