我必须让数据保密吗?

Do I have to make data private?

本文关键字:保密 数据      更新时间:2023-10-16

我知道类中的数据应该是私有的,然后使用getter和setter来读取/修改它们。但是比起直接使用student.scores.push_back(100),节省了一个成员函数,是不是很麻烦。

class Student {
public:
    void addToScores(int inScore) {
        scores.push_back(inScore);
    }
private:
    vector<int> scores;
}

简而言之,我很好奇人们实际上是怎么做的,总是严格私有的数据与getter和setter?

成员函数的目的是公开一个接口。不需要创建getter和setter或其他琐碎的函数,只需将成员已经实现的接口移动到聚合容器对象中。

如果允许Student的客户端任意操作scores,则应该使scores成为公共成员并以简单的方式访问它。如果它应该是一个只有pushpoptop的堆栈,那么使用std::stack接口适配器。如果只允许push_back,那么可以实现addToScores。但是,如果唯一的客户端是您,并且您不担心std::vector接口的其他部分被滥用,那么实现新接口确实没有意义。

程序中的每个接口都应该经过深思熟虑的设计。由于标准接口(包括c++的默认赋值操作符)是"危险的",所以将草率的接口添加为习惯不一定是一个好习惯。

在实践中,人们使用类来定义具有独立于其数据成员的新语义的新数据类型。既不使用访问器,也不使用公共数据成员,而是提供成员函数来执行与新数据类型相关的任务,同时维护数据成员的不变量。

当然,有时人们编写的类只是数据的聚合,没有额外的语义。在本例中,填充public成员的struct是合适的。

除了数据封装之外,使用Get/Set方法的一个基本原因是控制输入类型。

如果您不想接受某些特定的输入类型,例如您可能不想要分数超出[0,100]区间的界限,那么您可以在Set方法中检查此条件,以便库用户不能进行不合逻辑的操作。

如果它是一个简单的读/写操作,那么您实际上不必将数据设为私有。但是,如果需要对读/写的数据执行验证/条件,则将其设置为private是有意义的。