条款22 将成员变量声明为private

2024-08-28 04:18

本文主要是介绍条款22 将成员变量声明为private,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

总结:

     切记声明数据成员为private。它为客户提供了访问数据的一致,细微划分的访问控制,允许约束条件获得保证,而且为类的作者提供了实现上的弹性。

     protec并不比public更具有封装性


不应该将数据成员声明为public的三个理由

一、语法一致性

        如果数据成员不是public的,客户访问一个对象的唯一方法就是通过成员函数。如果在public接口中的每件东西都是函数,客户就不必绞尽脑汁试图记住当他们要访问一个类的成员时是否需要使用圆括号,他们只要使用就可以了,因为每件东西都是一个函数。


二、精确控制成员变量的处理

       如果你让一个数据成员为public,每一个人都可以读写访问它,但是如果你使用函数去得到和设置它的值,你就能实现禁止访问,只读访问和读写访问,甚至只写访问:

class AccessLevels {
public:...int getReadOnly() const { return readOnly; }void setReadWrite(int value) { readWrite = value; }int getReadWrite() const { return readWrite; }void setWriteOnly(int value) { writeOnly = value; }private:int noAccess; // no accessint readOnly; // read-only accessint readWrite; // read-write accessint writeOnly; // write-only access
};
三、封装:

       如果你通过一个函数实现对数据成员的访问,你可以以后改以某个计算来替换这个数据成员,使用你的类的人不会有任何察觉。

例如,假设你正在写一个自动测速程序,当汽车通过,其速度便被计算并填入一个速度收集器内:

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

        现在考虑成员函数averageSoFar的实现:办法之一是在类中用一个数据成员来实时变化迄今为止收集到的所有速度数据的平均值。无论何时averageSoFar被调用,它需返回那个数据成员的值。另一个方法是在每次调用averageSoFar时重新计算,通过分析集合中每一个数据值做成这些事情。

        谁能说哪一个最好?在内存非常紧张的机器(如,一台嵌入式路边侦测设装置)上,或是一个很少需要平均值的应用程序中,每次都计算平均值可能是较好的解决方案;在一个频繁需要平均值的应用程序中,速度比较重要,且内存不成问题,保持一个实时变化的平均值更为可取。重点在于通过一个成员函数访问平均值(也就是说将它“封装”),你能替换这两个不同的实现(也包括其他你可能想到的)。

        封装可能比它最初显现出来的更加重要。如果你对你的客户隐藏你的数据成员(也就是说,封装它们),你就能确保类的约束条件总能被维持,因为只有成员函数能影响它们。此外,你预留了日后变更实现的权利如果你不隐藏你将很快发现,即使你拥有类的源代码,你改变任何一个public的东西的能力也是非常有限的,因为有太多的客户代码将被破坏。public意味着没有封装,没有封装意味着不可改变,尤其是被广泛使用的类。被广泛使用的类是最需要封装的,因为它们可以从一种更好的实现中得益。



为什么不应该声明protected数据成员?

        反对protected数据成员的理由和public数据成员是类似的。关于语法一致性和细微划分之访问控制等理由显然也适用于protected数据,就连封装性上protected数据成员也不比public数据成员更好。

        某些东西的封装性与“当其内容改变时可能造成的代码破坏量“成反比。所谓改变,也许是从类中移除它(就像上述的averageSoFar)。

        假设我们有一个public数据成员,随后移除它,所有使用了它的客户代码都被破坏,其数量通常大得难以置信,因此public数据成员是完全未封装的。但是,假设我们有一个protected数据成员,随后我们移除了它。现在有多少代码会被破坏呢?所有使用了它的派生类都被破坏,典型情况下,代码的数量还是大得难以置信,因此protected数据成员就像public数据成员一样没有封装。在这两种情况下,如果数据成员发生变化,被破坏的客户代码的数量都大得难以置信。一旦你声明一个数据成员为public或protected,而且客户开始使用它,就很难再改变与这个数据成员有关的任何事情。有太多的代码不得不被重写,重测试,重文档化,或重编译。

       从封装的观点来看,实际只有两个访问层次:private(提供了封装)与其他(没有提供封装)


这篇关于条款22 将成员变量声明为private的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1113706

相关文章

Golan中 new() 、 make() 和简短声明符的区别和使用

《Golan中new()、make()和简短声明符的区别和使用》Go语言中的new()、make()和简短声明符的区别和使用,new()用于分配内存并返回指针,make()用于初始化切片、映射... 详细介绍golang的new() 、 make() 和简短声明符的区别和使用。文章目录 `new()`

java如何调用kettle设置变量和参数

《java如何调用kettle设置变量和参数》文章简要介绍了如何在Java中调用Kettle,并重点讨论了变量和参数的区别,以及在Java代码中如何正确设置和使用这些变量,避免覆盖Kettle中已设置... 目录Java调用kettle设置变量和参数java代码中变量会覆盖kettle里面设置的变量总结ja

Perl 特殊变量详解

《Perl特殊变量详解》Perl语言中包含了许多特殊变量,这些变量在Perl程序的执行过程中扮演着重要的角色,:本文主要介绍Perl特殊变量,需要的朋友可以参考下... perl 特殊变量Perl 语言中包含了许多特殊变量,这些变量在 Perl 程序的执行过程中扮演着重要的角色。特殊变量通常用于存储程序的

变量与命名

引言         在前两个课时中,我们已经了解了 Python 程序的基本结构,学习了如何正确地使用缩进来组织代码,并且知道了注释的重要性。现在我们将进一步深入到 Python 编程的核心——变量与命名。变量是我们存储数据的主要方式,而合理的命名则有助于提高代码的可读性和可维护性。 变量的概念与使用         在 Python 中,变量是一种用来存储数据值的标识符。创建变量很简单,

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

JS_变量

二、JS的变量 JS中的变量具有如下特征 1 弱类型变量,可以统一声明成var 2 var声明的变量可以再次声明 3 变量可以使用不同的数据类型多次赋值 4 JS的语句可以以; 结尾,也可以不用;结尾 5 变量标识符严格区分大小写 6 标识符的命名规则参照JAVA 7 如果使用了 一个没有声明的变量,那么运行时会报uncaught ReferenceError: *** is not de

C++/《C++为什么要有静态成员函数》

摘要        本文说明了什么是静态成员变量,什么是静态成员函数的概念,讨论了访问私有静态成员变量的三个方法。得出用静态成员函数访问静态私有成员变量是最佳方法即回答了“C++为什么要有静态成员函数“的问题。 类的静态成员 我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。静态成员在类的所有对象中是

使用条件变量实现线程同步:C++实战指南

使用条件变量实现线程同步:C++实战指南 在多线程编程中,线程同步是确保程序正确性和稳定性的关键。条件变量(condition variable)是一种强大的同步原语,用于在线程之间进行协调,避免数据竞争和死锁。本文将详细介绍如何在C++中使用条件变量实现线程同步,并提供完整的代码示例和详细的解释。 什么是条件变量? 条件变量是一种同步机制,允许线程在某个条件满足之前进入等待状态,并在条件满

axure之变量

一、设置我们的第一个变量 1、点击axure上方设置一个全局变量a = 3 2、加入按钮、文本框元件点击按钮文档框展示变量值。 交互选择【单击时】【设置文本】再点击函数。 点击插入变量和函数直接选择刚刚定义的全局变量,也可以直接手动写入函数(注意写入格式。) 这样点击按钮时就直接展示刚刚设置的全局变量3了。 2、更改变量值 在新建交互里点击设置变量值。 将a变量设置成等于10. 将新

shell脚本中变量中字符串替换的测试 /和//的区别

test_char=abbbcbbbf echo "bf:test_char = " $test_char test_char=${test_char/bbb/ddd} echo "af:test_char = " $test_char 输出: bf:test_char =  abbbcbbbf af:test_char =  adddcbbbf 只匹配第一个