繁体   English   中英

Setter / getters和分层数据结构

[英]Setters/getters and hierarchical data structures

我知道在你班上有公共领域被认为是个坏主意。 但是,当您的类包含众多分层数据结构和字段时,最好的方法是什么? 例如:

class A {B d1; C d2; D d3;}
class B {E d4; F d5;}
class E {G d6; int d7;}

在C中,访问这样的数据结构非常容易,例如ptr_to_A-> d1.d4.d7等等......但是当我们使用setter / getters时,方法是什么?

在C ++中使用setter和getter时,像A.get_d1()。get_d4()。get_d7()这样的表达式似乎不方便,它们强制返回引用。 由于某些结构非常大,按价值返回似乎是个糟糕的主意。

在这些情况下,您使用哪种方法或编码方式? 也许摆脱setter / getters并将这些领域公之于众?

在我的编码风格中,类不应该暴露公共“原始”数据成员,而应该只暴露getter和setter(即使它们是简单的单行方法)。

这是因为代码可以在将来升级,并且单行方法可以扩展到更复杂的东西(或者可以添加一些仅调试构建功能来检查一些不变量等),所以最好保持客户端的接口一致(如果您公开“原始”数据成员,这是不可能的)。

您可以避免使用get_()前缀,只需将数据成员视为具有简单(不带get_... )名称的“属性”,例如

class Shape
{
public:
  ....

  COLORREF Color() const // Just Color() i.e. the property name, without get_...
  {
     return m_color;
  }

private:
  COLORREF m_color;
};

并编写客户端代码,如:

Shape s;
COLORREF someColor = s.Color();

这对我来说很好看。

对于setter,您可以使用如下语法:

Shape& Color(COLORREF color)
{
    m_color = color;
    return *this;
}

并编写客户端代码,如:

Shape s;
s.Color(...).Draw(); // set color and draw shape

如果属性的类型比COLORREF (32位DWORD )更复杂,则可以使用如下模式:

std::wstring Name() const // getter
{
    return m_name;
}

Shape& Name(std::wstring name) // setter
{
    // Pass by value and move from the value (C++11 move semantics)
    m_name = std::move(name);

    return *this;
}

我知道在你班上有公共领域被认为是个坏主意。

这是来自上一个十年Java开发的全面声明。 您应该考虑成员应该是逐个成员公开还是私有。 有时公共数据成员是正确的想法。 请考虑以下问题:

  1. 我是否需要对此会员保持不变?
  2. 该成员可以使用无效值吗?
  3. 我是否希望界面为该成员提供替代表示?

如果上述任何问题的答案都是肯定的,那么您可能想要使用一个getter。

还要考虑单独设置成员是否真的有意义。 也许您应该使用构造函数设置成员,并且您希望提供一些修改这些成员的其他接口。

在C ++中使用setter和getter时,像A.get_d1()。get_d4()。get_d7()这样的表达式似乎不方便

虽然对数据结构进行相当深的嵌套并不常见,但通常一段特定的代码不应该深入研究它。 如果确实如此,我想它可能做得比它应该做的更多,超出了它的单一责任。 但是,如果它是一个共同的任务,以获得d7A对象,也许A应该暴露在其界面:

int A::get_d7 {
  return get_d1().get_d4().get_d7();
}

由于某些结构非常大,按价值返回似乎是个糟糕的主意。

实际上,使用现代C ++,这根本不是问题。 传递值应该被视为对象传递的默认模式。 这是因为现在可以移动临时对象,这实际上是一种非常有效的复制形式。

如果您只是将类用作纯数据结构,并且没有与要封装的数据相关的行为 ,则使用struct代替直接访问字段。 Bjarne Stroustrup推荐这种方法 这相当于使用一个class并将所有成员声明为public ,但将其称为struct则更清楚地表明它只不过是简单的数据集合。

如果您所做的不仅仅是存储数据,那么请使用getter和setter。

在C ++中使用setter和getter时,像A.get_d1()。get_d4()。get_d7()这样的表达式似乎不方便,它们强制返回引用。 由于某些结构非常大,按价值返回似乎是个糟糕的主意。

不,您可以选择是通过引用还是按值返回。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM