为什么让班级成员私有?

时间:2014-07-09 19:08:00

标签: class private public modifier

我已经学习了一段时间的C ++,但总是有这个问题困扰我(多年)。在学校,我们的讲师喜欢将类变量声明为私有。为了访问它,我们必须声明一个访问器来访问它。

有时我们甚至不得不让不同的班级成为朋友"为了访问它的元素。

我的问题是:为什么要这么麻烦?当我们通过公共利用一切来让我们作为程序员的生活变得更容易时,所有私人和受保护的东西背后的真正理由是什么?

我在想,一旦代码被编译,最终用户甚至不会区分我们是否在后端编码中使用公共或私有,那么为什么还需要将其正确地声明为私有,受保护......等等? / p>

3 个答案:

答案 0 :(得分:6)

让您的代码更易于理解和维护。

当您创建数据成员public时,使用您的类的其他程序员自然会倾向于使用这些公共成员而不是某些提供相似或相同信息的成员函数,因为它更容易。你甚至可能倾向于自己这样做。这是可以理解的 - 程序员本身就是lazy beasts

但是假设你在某个地方意识到成员函数提供的信息不再仅仅从那个成员变量生成。更糟糕的是,如果该成员变量在设计变更时变得过时,该怎么办?更糟糕的是,如果不删除成员变量本身,但它的语义会发生变化。

让我们考虑一个例子。假设您有一个代表您有待售物品的课程:

class Gizmo
{
public:
  std::string mSku;
};

就是这样,你所拥有的只是一个sku。假设mSku的内容只是产品编号,例如"12345"

你完成了代码,运送它,生活很棒。在您的公司变得像亚马逊一样成功之前,现在您开始从多个供应商那里获得相同的产品。您决定最好的事情是编码 mSku,以便它包含供应商信息以及产品编号。来自两个不同供应商的相同小部件可能具有非常不同的skus:S:12345Z:12345

任何编写的代码都希望mSku只是一个产品编号现在已被破坏,并且所有代码都必须重新计算。在这个愚蠢的小例子中,这可能是一个问题。想象一下100万行代码的代码库 - 根本不常见。您和您的所有同事可能已经忘记了所有使用mSku的地方。没有任何代码将无法编译,因此编译器没有帮助 - 但所有代码都被破坏了。这是一个很大的问题。

如果你根本没有依赖mSku,但是提供了一个签订合同以返回产品编号的会员功能,那么一开始会更好。类似的东西:

class Sku
{
public:
  std::string ProductNumber() const;
private: 
  std::string mSku;
};

现在,您可以根据需要更改mSku的语义。只要您重构ProductNumber()返回产品编号的内容,所有这100万行代码仍然可以编译并且仍然是正确的。

事实上,我通常更进一步。我通常会在class private中创建所有,直到有特定原因使其成为其他内容。即使这样,我也只会protected,除非我确实需要它public

  

[为什么我们不能]通过使用更容易让我们作为程序员的生活   公开一切吗?

在一个大型代码库中,即使它只由一个人维护,从长远来看,通过从一开始就制作大量这些东西private,您实际上可以让您的生活更轻松

答案 1 :(得分:5)

您标记了类成员private:,以减少使用您的代码的其他开发人员可能依赖的内容。在您发布代码供其他人使用的那一刻,他可以使用的所有内容都将成为您的维护责任。您不能简单地删除公共成员函数或更改其参数类型,因为这样做会破坏其他人的代码。

这就是为什么缩小必须保留的项目数量是有意义的,以便在更改类的实现时给自己更多的灵活性。如果某个成员是私人成员,您可以随意更改或删除该成员,而不会对使用您的代码的其他人造成任何问题。在团队中开发代码时,这一点非常重要。

答案 2 :(得分:0)

参见C ++标准11.1。

c ++中面向对象设计背后有一种哲学。

存在用于为其余代码提供可移植功能的对象。为了实现这一点,您应该能够指定下一个编码器如何使用您的对象(即使下一个编码器就是您)。

为了保持您的对象在该类的代码中被严格定义,它应该为它提供一个接口来实现它的功能。通常这只是吸气剂和制定者。编写这些内容是为了在您需要更改成员访问方式的情况下,这可以在您的课程中完成,而不是在其他地方完成。为确保这种情况,您的成员对象必须是私有的。