C++变成规范之41:将数据成员设为私有的,无行为的聚类(C语言形式的struct除外)

摘要:

    它们不关调用者的事:将数据成员设为私有的。简单的C语言形式的struct类型只是将一组值聚集在了一起,并不封装或者提供行为,只有在这种struct类型中才可以将所有数据成员都设成公用的。要避免将公用数据和非公用数据混合在一起,因为这几乎总是设计混乱的标志。

    信息隐藏是优秀软件工程的关键。应该将所有数据成员都设为私有的,不管是现在,还是可以能发生变化的将来,私有数据都是类用来保持其不变式的最佳方式。

    如果类要建模一个抽象,并因而必须维持一个不变式,那么使用公用数据就不好了。拥有公用数据意味着类的部分状态的变化可能是无法控制的、无法预测的、与其他状态异步发生的。这意味着抽象将与使用抽象的所有代码组成无限集合共同承担维持一个或者更多不变式的职责,这是一种显而易见的、根本性的、不可原谅的缺陷。应该断然拒绝这种设计。

    保护数据具有公用数据的所有缺点,因为拥有保护数据仍然意味着抽象将与代码的无限集合共同承担着一个或者更多不变式的职责,只不过这里的集合是由当前的派生类和未来的派生类组成的。而且,通过派生一个新类,并用它来获取数据,任何代码都能够像公用数据那样容易地读取和修改保护数据。

    在同一个类中混合使用公用和非公用数据成员既容易含混不清,又存在前后矛盾。私有数据表明具有不变式而且希望保持这种不变性,而将其与公用数据混合则意味着无法明确地判断这个类到底要不要成为抽象。

非私有数据成员甚至还不如简单的通道性的get/set函数,后者起码还能进行健壮的版本处理。

时间: 2024-10-31 20:59:34

C++变成规范之41:将数据成员设为私有的,无行为的聚类(C语言形式的struct除外)的相关文章

c#匿名方法的静态数据成员和实例数据成员用法

匿名方法总是以一个delegate关键字开始,后面跟着用在方法和方法体(the method body)本身中的参数.正如从上面示例中所见,用户不需要确定匿名方法的返回类型.它(译注:指返回类型)由方法体中的return语句推断而来..NET CLR不能执行像匿名方法一样的自由流(free flowing)代码块.CLR要求:它执行的每个方法是一个类型的一部分,并且应该是一个静态(static)方法或实例(instance)方法(译注:若一个方法声明中含有 static 修饰符,则称该方法为静态

C++中类的数据成员的安全隐患

在任何一本关于"C++语言程序设计"的书中都有类似于如下的描述: 在一个类中,C++用三个关键词设置访问界限:public, private和protected.它们决定了跟在他们后面的标识符的被使用情况:public意味着其后的标识符可以被用户定义的其实例引用:而private则说明其后的标识符除了类的成员函数之外,用户定义的其实例不能引用:protected为类的继承提供了接口,同时保护其不被外界访问. 事实上也,如果要想利用类的一个对象(或实例)来访问其成员时确实如此.但是,在C

C++类静态数据成员与类静态成员函数

在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? 这个问题便是本章的重点: 声明为static的类成员或者成员函数便能在类的范围内共同享,我们把这样的成员称做静态成员和静态成员函数. 下面我们用几个实例来说明这个问题,类的成员需要保护,通常情况下为了不违背类的封装特性,我们是把类成员设置为protected(保护状态)的,但是我们为了简化代码,使要说明的问题更为直观,更容易理解,我们在此处都设

Effective C#原则1:尽可能的使用属性(property),而不是数据成员(field)

我们的目标:尽可能编写出运行效率更高,更健壮,更容易维护的C#代码. 原则一:尽可能的使用属性(property),而不是数据成员(field). Always use properties instead of accessible data members. 出于以下几点原因,请在设计类时,尽可能的使用属性,而不 是成员. 1..Net对属性的支持远远大于对成员的支持,你可以对属性进 行数据绑定,设计时说明等很多数据成员不被支持的内容.看看.net里的属性面 板,你会明白的. 2.数据安全性

关于C++类的数据成员的存储类型,为什么不能是auto、register和extern

问题描述 关于C++类的数据成员的存储类型,为什么不能是auto.register和extern C++中类的存储类型不能是register和extern可以理解,但为什么不能是auto类型的呀?在结构体中同样出错,在函数中不出错,什么情况? #include<iostream> #include<cmath> using namespace std; class complex { private: auto double real;//编译时此处有错误illegal stora

c++-文件的读写,会将类对象的数据成员写入文件中。能将文件中的信息读入类对象的对应属性中。

问题描述 文件的读写,会将类对象的数据成员写入文件中.能将文件中的信息读入类对象的对应属性中. 情况一:无get,set,无<< >>重载函数的情况下如何将类对象的各个数据成员写入某个文件中(提示:可以在print函数中写代码). 情况二:当程序包含get,set函数而无<< >>重载函数时,如何将类对象的数据成员写入文件中. 情况三:当程序包含<< >>重载函数时,如何将类对象的数据成员写入文件中. 解决方案 大神在哪里,求,求大神

C# Json反序列化 数据协定类型 无法反序列化 因为未找到必需的数据成员

背景今天在使用:C# Json 序列化与反序列化 反序列化的时候出现了下面的错误信息. System.Runtime.Serialization.SerializationException: 数据协定类型"TestEntity"无法反序列化,因为未找到必需的数据成员"multipleChoice, runTimeDisplayColumns". 在 System.ComponentModel.ReflectPropertyDescriptor.SetValue(O

c++-C++中对类的一个数据成员排序,为什么排序不了

问题描述 C++中对类的一个数据成员排序,为什么排序不了 #include #include #include #include class List; class person { public: friend class List; private: person() {next=0;} person *next; char name[10],sex[5],tel[15],ads[20],code[10],mail[20],QQ[15],category[15]; }; class List

mfc-MFC 静态数据成员初始化

问题描述 MFC 静态数据成员初始化 要用到AfxBeginThread(threadproc,.....),函数threadproc()必须为静态函数,我使用这个函数需要调用 如下静态成员 但是我只能在 .cpp文件外部初始化为空.请问应该在哪给他们赋上后面的值,还是我的思路有问题. pStc=(CStatic *)GetDlgItem(IDC_STATIC); pStc->GetClientRect(&rect): pDC=pStc->GetDC(); hDC=pDC->Ge