我刚刚在第298页的C++ Primer(第5版)中阅读了以下定义:
在以下情况下,类是聚合:
它的所有数据成员都是公开的
它没有定义任何构造函数
它没有类内初始化器
它没有基类或虚函数
本文还提供了一个定义:什么是聚合和POD以及它们如何/为何特殊?.
毕竟我在本书的前几节中读到了封装的价值,我想知道:为什么有人想要使用聚合类?(顺便说一句,这个问题似乎适用struct于一般情况:我为什么要public:默认拥有?)
聚合基本上是一个简单的数据集合,没有必须class保证的任何不变量.由于没有不变量,因此成员的可能值的所有组合都有意义,因此没有必要保护它们是私有的.
这样一个类的一个简单例子就是这样的
struct Point3d {
std::array<double, 3> coordinates;
};
Run Code Online (Sandbox Code Playgroud)
由于doubles的每个三元组都是R ^ 3中的一个点,因此隐藏数据没有任何好处.(如果你害怕NaN和infinity价值观,这可能不是最好的主意.如果发生这种情况,你可能不想让它成为聚合.)
聚合类型的另一个例子是std::array.同样,它只是一个类型和一些(不可变)长度的数组,因此没有保持不变量.
聚合的一个优点是聚合初始化.
聚合类可以使用初始化列表进行聚合初始化:
struct Agg {
string a;
int b;
}
Agg a = {"A string", 0};
Run Code Online (Sandbox Code Playgroud)
它们主要用作类似元组的返回值,如下所示:
struct Response {
bool success;
string body; // Body is only set if success is true
}
Response foo() {
if(failed) return {false, ""};
return {true, "content"};
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,必须满足所有四个要求才能有意义(在 c++11 之前)。
其所有数据成员都是公开的
它几乎只是一个对象元组。
它没有定义任何构造函数
那么,要么初始化所有成员(通过聚合初始化),要么默认初始化所有成员(使用默认构造函数)。
它没有类内初始化程序
与上面相同
它没有基类或虚函数
它类似于元组,因此基类会破坏它,并且虚函数没有意义,因为您不会从这样的类继承。
我希望这能澄清一点。请记住,这是在 C++11 之前发明的,在 C++11 之前std::tuple是不存在的,因此您可以使用聚合类来返回多个值。如今,在大多数用例中,您tuple也可以使用,但这不是我最喜欢的。
std::tuple与聚合类别大多数时候,聚合课程是正确的选择。仅当您确实只想返回对象元组,然后“将其分解为多个部分”时,才应使用元组。成员函数在大多数情况下没有意义,但聚合类仍然可以重载强制转换运算符。
仅当您只想将一堆对象重新调整在一起而无需执行任何操作时才使用元组,而无需为它们“命名”(通过聚合中的成员名称)