Effective C++条款22解读: 将成员变量生命为private
2015-06-21 16:07
393 查看
我们先来看一个简单的程序:
为什么会产生这样的尴尬局面呢? 原来, 类的使用者直接操作了成员变量, 这不是类的使用者的错, 而是类的提供者的错, 所以, 在提供类的时候, 不要把成员变量定义为public, 我们来改一下第一个程序:
上面仅仅从程序可扩展性的角度考虑用private封装数据成员, 那还有没有别的原因呢? 肯定有, 你想想, 如果类的使用者能直接操作数据成员, 那还得了。 所以, 从安全性的角度来考虑, 也该用private.
Scott Meyers也说了, 用protected会存在类似的问题。 所以, 在Effective C++中, 作者强调:将成员变量生命为private(而不是public或者protected, 实际上, protected并不会比public号多少)
其实, 将成员变量生命为private, 这个条款是很好理解的, 最近买了一个iphone 6 plus, 果果手机把内部封锁得这么严, 其实与我们把类封锁得严严实实的, 是同一个道理。 让用户接触该接触的, 接触不到不该接触的。
#include <iostream> #include <string> using namespace std; // 类的提供者 class Programmer { public: string name; string address; // 如下的两个const不可少 void set(const string &tmpName, const string &tmpAddress) { name = tmpName; address = tmpAddress; } }; // 类的使用者 int main() { Programmer pro; pro.name = "eric"; pro.address = "China"; return 0; }当然, 这个程序运行肯定是没有问题的, 但某一天, 类的提供者觉得address这个名称太长太恶心, 想换成addr, 于是就成了这样的程序:
#include <iostream> #include <string> using namespace std; // 类的提供者 class Programmer { public: string name; string addr; // 如下的两个const不可少 void set(const string &tmpName, const string &tmpAddr) { name = tmpName; addr = tmpAddr; } }; // 类的使用者 int main() { Programmer pro; pro.name = "eric"; pro.address = "China"; return 0; }显然, 类的使用者没法觉察到改变, 程序编译有错。 即使类的提供者告诉类的使用者要改变address字段, 那你想想, 类的使用者该有多恼火啊, 如果程序非常大, 那就更加糟糕了。
为什么会产生这样的尴尬局面呢? 原来, 类的使用者直接操作了成员变量, 这不是类的使用者的错, 而是类的提供者的错, 所以, 在提供类的时候, 不要把成员变量定义为public, 我们来改一下第一个程序:
#include <iostream> #include <string> using namespace std; // 类的提供者 class Programmer { private: string name; string address; public: // 如下的两个const不可少 void set(const string &tmpName, const string &tmpAddress) { name = tmpName; address = tmpAddress; } }; // 类的使用者 int main() { Programmer pro; pro.set("eric", "China"); return 0; }此时, 如果类的提供者再改变, 就不要通知类的使用者了, 而且类的使用者也确实不需要做出任何改变, 我们看来看类的提供者将address改为addr后的情况:
#include <iostream> #include <string> using namespace std; // 类的提供者 class Programmer { private: string name; string addr; public: // 如下的两个const不可少 void set(const string &tmpName, const string &tmpAddr) { name = tmpName; addr = tmpAddr; } }; // 类的使用者 int main() { Programmer pro; pro.set("eric", "China"); return 0; }编译通过, 程序OK, 类的使用者完全不知道有变更这回事. 看看, 责任清晰, 多好啊。
上面仅仅从程序可扩展性的角度考虑用private封装数据成员, 那还有没有别的原因呢? 肯定有, 你想想, 如果类的使用者能直接操作数据成员, 那还得了。 所以, 从安全性的角度来考虑, 也该用private.
Scott Meyers也说了, 用protected会存在类似的问题。 所以, 在Effective C++中, 作者强调:将成员变量生命为private(而不是public或者protected, 实际上, protected并不会比public号多少)
其实, 将成员变量生命为private, 这个条款是很好理解的, 最近买了一个iphone 6 plus, 果果手机把内部封锁得这么严, 其实与我们把类封锁得严严实实的, 是同一个道理。 让用户接触该接触的, 接触不到不该接触的。
相关文章推荐
- C++的try_catch异常
- C++ 多重继承和虚拟继承的内存布局(vtable,vptr)
- 常用的内排序算法与C++实现
- 国王的烦恼
- C语言回顾(五、函数,递归,Hanoi汉诺塔,整数转字符串)——iOS开发基础
- c++学习-虚函数
- 在C语言中的字符串
- 黑马程序员——C语言基础知识整理——printf函数与scanf函数
- 第14周项目4-处理C++源代码的程序
- 第十四周 【项目2-用文件保存的学生名单】若干名学生的学号 姓名和C++课、高数和英语成绩
- C++的4种类型转换关键字及其特点
- 注释转换 ——C注释转换为标准C++注释
- 从大学开始学C++到现在的一些感悟
- c++基础编程 之 string
- 【读书笔记:C++ primer plus 第六版 中文版】第4章 复合类型
- 双边滤波原理与C++实现
- c++学习-继承
- 第十五周oj刷题——Problem A: 长方柱类【C++ 类定义】
- 第十五周oj刷题——Problem B: 矩形类定义【C++】
- 第十五周oj刷题—— Problem C: 矩形类中运算符重载【C++】