受保护数据成员的受保护获取函数?

Protected get-functions for protected datamembers?

我们有两个 classes(A 和 B)。 Class A只能由继承它的classes创建(class A) 并且 class B 可以由用户创建。

Class A,版本 1 有一个 private 数据成员,并且有在 class A.

中获取数据的方法

Class A,版本 2 有一个 protected 数据成员,因此,classes 不需要任何方法来继承 class 对 class A

中的数据进行 ace

Class一、版本1

class A
{
protected:
   A() = default;

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

Class一、版本2

class A
{
protected:
   A() = default;

   T data;  
}

Class B

class B : public A {}

哪个版本的 class A 是首选?

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

这是相当主观的,但我会说 95% 的情况下两者都不是。受保护的数据使您的代码与 public 一样难以维护,因此我们立即排除该版本。但是你几乎永远不需要直接的 mutator (set) 函数,所以我们将砍掉那个函数,然后将 get 函数的签名更改为 const T& get_data() const;。然后我们将向父级添加一个 真实 接口来操纵其状态,而不是让外部的东西决定新状态应该是什么。

如果除了简单访问变量之外还需要其他任何东西,请使用访问器函数:验证值、维护 class 不变量、信号更改、日志记录等。请注意 get 应该 return 一个值或一个 const 引用;您的版本 returning 非常量引用可用于为变量分配任意值,绕过 set 函数。

如果您只需要简单的访问,那么为了简单起见,有些人会建议公开变量;其他人会建议使用访问器函数以保持一致性(与其他确实需要此类东西的类型)或向后兼容性(如果您后来决定毕竟需要函数)。没有令人信服的理由选择任何一个选项。

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

但是,protected的情况下没有这样的例外。您始终可以将它们设为私有并向这些数据成员提供 accessors/mutators。

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

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

除此之外,您绝不会像在以下情况中那样将内部结构的句柄传递给外部用户:-

T& get_data();

所以,更好的方法是

const T& get_data();

除了某些特定情况。