Item 22:数据成员应声明为私有 Effective C++笔记
2015-09-06 16:30
288 查看
Item 22: Declare data members private
数据成员声明为私有可以提供一致的接口语法,提供细粒度的访问控制,易于维护类的不变式,同时可以让作者的实现更加灵活。而且我们会看到,
你肯定也遇到过这种困惑,是否应该加括号呢?
总是难以记住如何获取该属性,是调用一个
为数据成员提供getter和setter可以实现对数据更加精细的访问控制,比如实现一个只读的属性:
事实上,在C#中提供了访问器(又称属性)的概念, 每个数据成员都可以定义一套访问器(包括setter和getter),使用访问器不需要使用括号:
封装所有的数据可以方便以后类的维护,比如你可以随意更改内部实现,而不会影响到既有的客户。例如一个
你的实现方式的变化不会影响到你的客户。但如果
那么对于你的每次实现方式变化,客户就必须重新实现、重新编译、重新调试和测试它们的代码了。
既然共有数据成员会破坏封装,它的改动会影响客户代码。那么
面向对象的精髓在于封装,可以粗略地认为一个数据成员的封装性反比于它的改动会破坏的代码数量。比如上述的
large amount)。如果是
unknowably large。
除非注明,本博客文章均为原创,转载请以链接形式标明本文地址: http://harttle.com/2015/08/19/effective-cpp-22.html
数据成员声明为私有可以提供一致的接口语法,提供细粒度的访问控制,易于维护类的不变式,同时可以让作者的实现更加灵活。而且我们会看到,
protected并不比
public更加利于封装。
语法一致性
你肯定也遇到过这种困惑,是否应该加括号呢?obj.length // 还是 obj.length()? obj.size // 还是 obj.size()?
总是难以记住如何获取该属性,是调用一个
getter?还是直接取值?如果我们把所有数据都声明为私有,那么在调用语法上,统一用括号就好了。
访问控制
为数据成员提供getter和setter可以实现对数据更加精细的访问控制,比如实现一个只读的属性:class readOnly{ int data; public: int get() const { return data; } }
事实上,在C#中提供了访问器(又称属性)的概念, 每个数据成员都可以定义一套访问器(包括setter和getter),使用访问器不需要使用括号:
public class readWrite{ private string _Name; public string Name{ set { this._Name = value; } get { return this._Name; } } } ReadWrite rw; // 将会调用set方法 rw.Name = "alice";
可维护性
封装所有的数据可以方便以后类的维护,比如你可以随意更改内部实现,而不会影响到既有的客户。例如一个SpeedDataCollection需要给出一个平均值:
class SpeedDataCollection{ public: void add(int speed); double average() const; };
average()可以有两种实现方式:维护一个当前平均值的属性,每当
add时调整该属性;每次调用
average()时重新计算。两种实现方式之间的选择事实上是CPU和内存的权衡,如果在一个内存很有限的系统中可能你需要选择后者,但如果你需要频繁地调用
average()而且一点内存不是问题,那么就可以选择前者。
你的实现方式的变化不会影响到你的客户。但如果
avarage()不是方法而是一个共有数据成员。
那么对于你的每次实现方式变化,客户就必须重新实现、重新编译、重新调试和测试它们的代码了。
来看看 protected
既然共有数据成员会破坏封装,它的改动会影响客户代码。那么protected呢?
面向对象的精髓在于封装,可以粗略地认为一个数据成员的封装性反比于它的改动会破坏的代码数量。比如上述的
average如果是一个
public成员,它的改动会影响到所有曾使用它的客户代码,它们的数量是大到不可知的(unknowably
large amount)。如果是
protected成员,客户虽然不能直接使用它,但可以定义大量的类来继承自它,所以它的改动最终影响的代码数量也是
unknowably large。
protected和
public的封装性是一样的!如果你曾写了共有或保护的数据成员,你都不能随意地改动它们而不影响客户代码!
除非注明,本博客文章均为原创,转载请以链接形式标明本文地址: http://harttle.com/2015/08/19/effective-cpp-22.html
相关文章推荐
- c++builder XE8 线程 Thread
- C++ 牛人博客(不断更新中...)
- C/C++题目总结【来自牛客网】
- 顺序表的基本操作——C++实现
- c++在vector的遍历
- k近邻算法C++二维情况下的实现
- 数组初始化(c, c++, gcc, g++)
- C语言几个预编译指令的用法
- 详解C语言中的ttyname()函数和isatty()函数的用法
- c++ 要点记录
- cpp 考试算法
- 最小堆&&最大堆的实现(c++)
- C语言中getopt()函数和select()函数的使用方法
- C++基础
- 最小堆的C++实现
- C++成员变量初始化与构造函数
- C++builder自绘控件框架
- 【C++】虚函数
- C++入门经典 笔记 (第十九章)使用链表存储信息
- c++学习笔记-动态绑定