为什么不使用public成员变量
- 语义一致性
如果成员变量都不是public,那我们必然是通过成员函数来访问对象,所以再也不用担心什么时候用接口,什么时候用属性了。
另外,使用函数可以对变量进行更加精准的控制,你完全可以实现只读,读写,或者不予读写,甚至只写操作。举例而言:1
2
3
4
5
6
7
8
9
10
11
12
13class AccessLevels{
public:
...
int getReadOnly() const{return readOnly;}
void setReadWrite(int value) {readWrite=value;}
int getReadWrite() const {return readWrite;}
void setWriteOnly(writeOnly=value;}
private:
int noAccess;//禁止访问
int readOnly;//只读
int readWrite;//读写
int writeOnly;//只写
} - 封装性
将成员变量隐藏在函数接口之后,可以为“所有实现的可能”提供弹性,我们可以在不改变接口的同时更改实现,从而保证了用户只需要在重新编译后即可享有与原先不同的体验。(Effective C++ 31 甚至提出了编译分离)
封装的重要程度可能比你想的还要更加高一些,如果你对客户隐藏了成员变量,那么至少可以保证class的约束条件总能获得维护,因为只有成员函数可以影响它们,并且开发者保留了日后变更实现的权利。如果不进行封装,那么客户码中将充斥着大量的成员变量,这也意味着我们无法随意地更改原有程序,因为每一次改动都可能造成客户端失效。public意味着不封装,不封装意味着不可改变,因为你一变用户也要跟着变。
protected的封装性
</br>
可能你会认为protected的封装性要高于public,但事实并非如此。因为所有使用了该变量的derived classes都遭到了破坏。一旦你将某个成员变量设为public或protected,并且随后交付客户使用,那你在今后就很难改变该变量所涉及的一切,除非你愿意付出重写、重新测试、重新编文档、重新编译的代价。
从封装的角度而言,访问权限只有两种:private(提供封装)和其他(不提供封装)。
总结
- 将成员变量声明为privte。这可赋予客户语义一致性,访问权限控制,并且令class作者拥有充分的实现弹性。
- protected并不比public更具封装性