刚开始接触OOP的时候,打心底里我不喜欢private与protected。我声明一个public然后不直接用它,不就跟private一样吗?在某些场合下,我还能偷偷地用一下public变量,这不是更方便吗?所以,以前写的class,除了class几个字母外,其它的跟struct没啥区别。做了几个小项目之后,我终于浪子回头。下面进入今天的正题——爱上private吧。

理由1。。。

假如一个member value不是public,唯一能够访问它的就是friend和API。我想,没有人会希望在写程序的时候喜欢因考虑是否需要()而浪费时间。所以,将member value声明为private,直观上能帮助我们减少这方面搔首挠耳的时间。比如,下面的这个例子,

class AccessLevels
{
public:
int getReadOnly();
int setReadOnly();
int setWriteOnly();
...
private:
int readOnly;
int writeOnly;
...
};

使用的时候,我们会毫不犹豫地加上()。还不止这些,假如你将member value设置为public,有一天你头晕晕地在A脚本中对readOnly修改为0,然后再B脚本百思不得其解的时候,你就会发现private在保护你的menber value时起到的作用了。

理由2。。。

也许,上面的例子还不足以让你信服,就像当初我刚学OOP时抵触private一般。下面我们换个高级一点的角度来看待这个问题:封装。再来一个简单的例子.

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

averageSoFar()的实现方式有两种,一种是添加一个成员变量,记录到现在为止所有速度的平均值。一种是调用的时候,收集所有速度值,然后再求平均值。

第一种方法会让SpeedDataCollection对象变大,多出的空间用于存放目前的平均值,累积总量,数据数量。但是averageSoFar十分高效。第二种方法不用记录很多内容,但是每次都需要计算,执行比较慢。

试想一下,在一台路边的测速装置上,能有多少内存能够使用。并且也不是每时每刻都需要平均速度,对于这种仪器,使用第一种方法比较合适。而假如我们要在屏幕上面显示当前赛车的平均速度,对于averageSoFar的性能要求就会非常高,所以采用第二种方式比较合适。而客户使用averageSoFar的时候,只会知道效果不错,但是却不用关心背后的实现方式。这就是使用private变量,也就是封装带来的好处,将member隐藏在接口后面,让所有可能的实现变得有弹性。

理由3。。。

最近在使用Unity3D开发游戏,虽然使用的是C#,但是由于使用了过多的public变量让人的确非常头痛。比如,NPC的状态使用一个state变量进行标记,在跑道上,NPC的状态千变万化,也就是在客户的代码上,不断地修改着NPC的状态。比如,使用了一个保护罩,在保护的时间再使用一个保护罩,每个保护罩在消失的时候就会将state从保护状态更改为非保护状态。那么第一个保护罩消失的时候发生了什么事呢?第二个保护罩还在,但是状态已经是非保护状态了。这个时候就非常头疼了,因为使用到state的客户端代码非常多,很难在茫茫人海中找到那个它(bug)。

假如state为private,那么访问它的只有SetState()与GetState(),那么当程序出问题的时候,我或许只需要关注这两个函数的实现方式即可。这多么让人惊讶!!!一开始使用public是为了方便,最后却发现private提供了更多的便利!!!

再举个栗子,我们在程序的后期取消了public ... state变量,那么有多少代码会受到影响呢?那往往是一个不可知的大量。

最后,为什么说使用private而不使用protected呢?##

客户是有相对的,比如,主函数中的代码可以是类的客户,而派生类也可以是客户。假如我们使用了protected,意味着在derived class中可以随心所欲地修改base class中的protected成员。把理由3照搬到这里来依然成立。由此可以看出,当存在继承的时候,base class中的protected与public同样不具备封装性。

为了更好更方便地活着——爱上private的更多相关文章

  1. Dnsmasq安装与配置-搭建本地DNS服务器 更干净更快无广告DNS解析

    默认的情况下,我们平时上网用的本地DNS服务器都是使用电信或者联通的,但是这样也导致了不少的问题,首当其冲的就是上网时经常莫名地弹出广告,或者莫名的流量被消耗掉导致网速变慢.其次是部分网站域名不能正常 ...

  2. 采用ADM2483磁隔离器让RS485接口更简单更安全

    采用ADM2483磁隔离器让RS485接口更简单更安全 摘要:本文介绍RS485的特点及应用,指出了普通RS485接口易损坏的问题,针对存在的问题介绍了以ADM2483为核心的磁隔离解决方案. 关键词 ...

  3. 正则表达式匹配可以更快更简单 (but is slow in Java, Perl, PHP, Python, Ruby, ...)

    source: https://swtch.com/~rsc/regexp/regexp1.html translated by trav, travmymail@gmail.com 引言 下图是两种 ...

  4. 金蝶随手记团队分享:还在用JSON? Protobuf让数据传输更省更快(实战篇)

    本文作者:丁同舟,来自金蝶随手记技术团队. 1.前言 本文接上篇<金蝶随手记团队分享:还在用JSON? Protobuf让数据传输更省更快(原理篇)>,以iOS端的Objective-C代 ...

  5. 更轻更快的Vue.js 2.0与其他框架对比(转)

    更轻更快的Vue.js 2.0 崭露头角的JavaScript框架Vue.js 2.0版本已经发布,在狂热的JavaScript世界里带来了让人耳目一新的变化. Vue创建者尤雨溪称,Vue 2.0  ...

  6. EpiiServer 更快捷更方便的php+nginx环境定制化方案

    EpiiServer是什么 更快捷更方便的php+nginx多应用部署环境. github仓库首页 https://github.com/epaii/epii-server gitee仓库 https ...

  7. 线程安全使用(四) [.NET] 简单接入微信公众号开发:实现自动回复 [C#]C#中字符串的操作 自行实现比dotcore/dotnet更方便更高性能的对象二进制序列化 自已动手做高性能消息队列 自行实现高性能MVC WebAPI 面试题随笔 字符串反转

    线程安全使用(四)   这是时隔多年第四篇,主要是因为身在东软受内网限制,好多文章就只好发到东软内部网站,懒的发到外面,现在一点点把在东软写的文章给转移出来. 这里主要讲解下CancellationT ...

  8. Mockplus更快更简单的原型设计

    更快更简单的原型设计 https://www.mockplus.cn/ Mockplus,更快更简单的原型设计工具.快速创建原型,一键拖拽创建交互,团队协作省事省力.微软.华为.东软.育碧.Oracl ...

  9. Google 开源的依赖注入库,比 Spring 更小更快!

    Google开源的一个依赖注入类库Guice,相比于Spring IoC来说更小更快.Elasticsearch大量使用了Guice,本文简单的介绍下Guice的基本概念和使用方式. 学习目标 概述: ...

随机推荐

  1. Flask知识总汇

    Flask基础 Flask基础使用与配置 Flask路由系统与模板系统 Flask视图函数 Flask请求与响应 Flask的session操作 Flask中间件 Flask连接数据库 Flask使用 ...

  2. Mirror--镜像用户同步

    --=========================================--在镜像搭建后,在主库服务器上创建登录,并在数据库上建立对应用户,--数据库中用户被同步到镜像数据库中,但登录是 ...

  3. /etc/rc.d/rc.local linux启动自动开启某些服务(转)

    /etc/rc.d/rc.local似乎是很多Linux系统管理员的偏爱,因为凡是需要随系统自动启动的服务.程序等,只要系统没有提供Sys V风格的启动脚本,就把这些需求都塞到/etc/rc.d/rc ...

  4. Linux光标移动异常

    刚刚安装完毕CentOS7.5,进行基础优化来着,发现我的光标具有如下神奇的故障. 无法移动到头部? 刚开始还以为是ISO镜像的问题,后校验了阿里云官网镜像的MD5值,和本地镜像MD5对比之后, 发现 ...

  5. java对象,引用的区别

    一,其实 对象 就是一个类的实例 在Java中有一句比较流行的话,叫做“万物皆对象”,这是Java语言设计之初的理念之一.要理解什么是对象,需要跟类一起结合起来理解.下面这段话引自<Java编程 ...

  6. java之标记型接口Cloneable

    1.克隆用途. Cloneable和Serializable一样都是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用Object.clone() ...

  7. Educational Codeforces Round 54 (Rated for Div. 2) Solution

    A - Minimizing the String solved 题意:给出一个字符串,可以移掉最多一个字符,在所有可能性中选取一个字典序最小的. 思路:显然,一定可以移掉一个字符,如果移掉的字符的后 ...

  8. fiddler抓包HTTPS配置及代理设置

    使用fiddler抓包过程中遇到一系列的问题,浪费了大半天时间~~~写下解决办法 按照网上方法配置之后还是无法抓到cookies提示各种证书错误 1.卸载fiddler重新安装,设置 2.设置步骤 ( ...

  9. HDU 3339 In Action(最短路+背包)题解

    思路:最短路求出到每个点的最小代价,然后01背包,求出某一代价所能拿到的最大价值,然后搜索最后结果. 代码: #include<cstdio> #include<set> #i ...

  10. 【大型web架构】一个大型web系统架构设计和技术选型的讨论摘录

    1.数据库压力问题 所有的压力最终都会反映到数据库方面,一定要对数据库有一个整体的规划. 可以按照业务.区域等等特性对数据库进行配置,可以考虑分库.使用rac.分区.分表等等策略,确保数据库能正常的进 ...