受保护的数据库的受保护的get函数?

时间:2015-01-07 15:58:23

标签: c++ class inheritance

我们有两个班级(A和B)。 A类只能由从中继承的类创建(A类) 和B类可以由用户创建。

A类,版本1有一个私有数据成员,并且有方法来接收A类数据。

A类,版本2有一个受保护的数据成员,因此,对于将继承自该类以接收A类数据的类,不需要任何方法

A类,第1版

class A
{
protected:
   A() = default;

   void set_data( T d );
   T& get_data();
private:
   T data;  
}

A类,第2版

class A
{
protected:
   A() = default;

   T data;  
}

B类

class B : public A {}

哪个版本的A类是首选版本?

4 个答案:

答案 0 :(得分:2)

这是相当主观的,但我会说95%的时间都不是。受保护的数据使您的代码与公共代码一样难以维护,因此我们立即对该版本进行了规则。但是你也几乎不需要直接的mutator(set)函数,因此我们将切断该函数,然后将get函数的签名更改为const T& get_data() const;。然后我们将向父级添加一个真正的接口来操纵它的状态,而不是让外部的东西决定新状态应该是什么。

答案 1 :(得分:0)

如果您遵循通用准则,则数据成员应该是私有的。因此,版本1是优选的。另一方面,在我看来,完全琐碎的get / set对是一个次要的代码气味,所以你可能想要调查为什么该成员首先需要完全暴露给派生类。

答案 2 :(得分:0)

如果您需要除了对变量的简单访问之外的任何其他内容,请使用访问器函数:验证值,维护类不变量,发送信号更改,记录等。请注意get应返回值或{{1参考;您的版本,返回非const引用,可用于为变量分配任意值,绕过const函数。

如果您只需要简单访问,那么为了简单起见,有人会建议公开变量;其他人会建议使用访问器函数以保持一致性(与需要此类事物的其他类型)或向后兼容性(如果您以后决定需要函数)。没有令人信服的理由更喜欢这两种选择。

答案 3 :(得分:0)

您的第一版始终是首选。默认情况下,类的数据成员应为private。使数据成员全部公开仅在一种情况下是合理的,即如果您只想捆绑数据。只有这样,您才会使用struct并公开所有数据。 (想捕捉链表中单个节点的本质)

但是,protected的情况下没有这种例外。您始终可以将它们设为私有,并为这些数据成员提供访问者/变更器。

public数据成员的缺点是他们打破了封装。并且很难维护不变量,因为数据可以从各方面进行修改。 protected数据成员的情况比public略有限制,因为它只通过派生类成员和朋友开辟了修改方式。但它仍然打破了封装。

结论: - 类的所有数据成员应始终为private,除非它打算用作bundle-o-data

除此之外,您永远不会像以前那样将句柄传递给外部用户: -

T& get_data();

所以,更好的方法是

const T& get_data();

除了某些特定情况外。