[英]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开发的全面声明。 您应该考虑成员应该是逐个成员公开还是私有。 有时公共数据成员是正确的想法。 请考虑以下问题:
如果上述任何问题的答案都是肯定的,那么您可能想要使用一个getter。
还要考虑单独设置成员是否真的有意义。 也许您应该使用构造函数设置成员,并且您希望提供一些修改这些成员的其他接口。
在C ++中使用setter和getter时,像A.get_d1()。get_d4()。get_d7()这样的表达式似乎不方便
虽然对数据结构进行相当深的嵌套并不常见,但通常一段特定的代码不应该深入研究它。 如果确实如此,我想它可能做得比它应该做的更多,超出了它的单一责任。 但是,如果它是一个共同的任务,以获得d7
从A
对象,也许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.