setter /getter和分层数据结构
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/getter的方法是什么呢?
在c++中使用setter和getter时,像A.get_d1().get_d4().get_d7()这样的表达式似乎不太方便,它们强制返回引用。由于一些结构非常大,按值返回似乎是一个糟糕的主意。
在这些情况下您使用哪种方法或编码风格?也许去掉setter/getter,让这些字段公开?
我知道在你的类中有公共字段被认为是一个坏主意。
这是来自过去十年Java开发的一个全面的声明。您应该在逐个成员的基础上考虑一个成员应该是公共的还是私有的。有时,公共数据成员是正确的想法。考虑以下问题:
- 我需要在这个成员上维护一个不变量吗?
- 这个成员可以有一个无效的值吗?
- 我是否希望接口给出该成员的替代表示?
如果以上任何一个问题的答案是肯定的,那么你可能需要使用getter。
还要考虑单独设置成员是否有意义。也许您应该使用构造函数设置成员,并且希望提供一些其他接口来修改这些成员。
在c++中使用setter和getter时,像a.t get_d1().get_d4().get_d7()这样的表达式似乎不太方便
虽然有相当深的数据结构嵌套并不罕见,但通常一段特定的代码不应该研究得太深。如果是这样,我想它可能做得比它应该做的更多,超出了它的单一责任。然而,如果从A
对象中获取d7
是一个常见的任务,也许A
应该在其接口中公开它:
int A::get_d7 {
return get_d1().get_d4().get_d7();
}
由于某些结构非常大,按值返回似乎是一个糟糕的主意。
实际上,在现代c++中,这根本不是问题。按值传递应该被视为对象传递的默认模式。这是因为现在可以移动临时对象,这实际上是一种非常有效的复制形式。
在我的编码风格中,类不应该公开公共的"原始"数据成员,而应该只公开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;
}
如果您只是将类用作纯粹的数据结构,并且没有与您想要封装的数据相关的行为,则使用struct
代替并直接访问字段。Bjarne Stroustrup推荐这种方法。这相当于使用class
并将所有成员声明为public
,但将其称为struct
可以更清楚地表明它只不过是一个简单的数据集合。
如果你要做的不仅仅是存储数据,那么就使用getter和setter。
在c++中使用setter和getter时,像A.get_d1().get_d4().get_d7()似乎不方便,而且它们强制返回引用。因为有些结构非常大,返回按价值计算似乎是个糟糕的主意。
不,您可以选择是按引用返回还是按值返回。
- 链表,反向函数,数据结构
- 如何使用set实现无序数据结构?
- 我们可以将数据永久保存为数据结构吗?
- C++中的可变长度数组/数据结构
- 用于存储由空格分隔的字符串的 C++/C 数据结构
- 通过 NIF 从C++返回自定义数据结构
- 编译器上的策略数据结构不起作用
- 尝试构建"lock-free"数据结构C++
- 设计将引用元素移动到开头的数据结构.C++
- 在学习数据结构之前对STL有一个了解是好的吗?
- 如何解析表示树状数据结构的字符串
- 我对数据结构、双向链表有一些问题
- googletest:测试太大的数据结构
- C++中deque数据结构的大O是什么?
- 我可以使用哪种数据结构来处理这种方式
- 将文本文件解析为树状数据结构
- C++ 中具有 O(1) 搜索时间复杂度的数据结构
- c++中带有向量的分层数据结构,可以自底向上和自顶向下遍历
- setter /getter和分层数据结构
- C++分层表示2D顶点、线段和三角形的数据结构(缓冲区)