C++ Aggregate 与 POD(Plain Old Data)的解释

无论是 Aggregate 还是 POD(Aggregates的升级版)都是对用来约束初始化的精巧的概念

motivation

当我们欲构造如下的union时:

union
{
    int i;
    std::string s;
                    // illegal: std::string is not a POD type!
} u;

vs 2013会对之作进一步的错误说明:

error C2621: “<unnamed-tag>::s: 非法的联合成员;
类型“std::basic_string<char,std::char_traits<char>,std::allocator<char>>”具有复制构造函数 

两者一规约,也即POD数据类型不允许使用其具有复制构造函数;
而且我们还可看到:
所谓的std::string类型其实是对std::basic_string<>某一特化版本的类型定义:

typedef basic_string<char, char_traits<char>, allocator<char> >
    string;

解释:Aggregates vs POD

如果想深入了解 POD(Plain Old Data)的话,了解 aggregates(聚合,集成?) 是必须的。

首先我们来看C++标准对 aggregates 的定义:

An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).

也即,首先所有的数组都是Aggregates,然后类类型如果满足那四个条件,等等,标准未对结构体(structs)以及联合体(unions)做任何说明。难道它们就不能成为aggregates了吗?可以的。在C++中,术语(关键字) class 表示所有的类、结构体以及联合。

那么,这四条关于类(class)的约束说明了:

  • 并非意味着一个 aggregate class 不可以拥有构造函数,事实上,它们可以拥有一个默认构造函数(default constrctor)以及(或者)一个拷贝构造函数只有它们被编译器隐式地声明,而非被用户显式地声明。

  • no private or protected non-static data members。You can have as many private and protected member functions (but not constructors) as well as as many private or protected static data members and member functions as you like and not violate the rules for aggregate classes。静态成员可以出现在任何位置,非静态成员只得以公共成员(public)的形式出现。

  • An aggregate class can have a user-declared/user-defined copy-assignment operator and/or destructor。结合第一条,也即如果想要出现构造函数的话,必须以拷贝构造的形式出现(operator=),

  • An array is an aggregate even if it is an array of non-aggregate class type.

下面我们来看一些具体的例子:

class NotAggregate1
{
    virtual void f() {}    // no virtual functions
};

class NotAggregate2
{
    int x;                 // x is private by default and non-static    
};

class NotAggregate3
{
public:
    NotAggregate3(int) {}   // user-defined ctor    
};

class Aggregate1
{
public:
    NotAggregate1 member1;    
                                // ok, public member
    Aggregate1& operator(const Aggregate1& rhs) {// }
                                // ok, copy-assignment
private:
    void f() {}
                                // ok, non-virtual function
};

现在我们来说明,为什么会提出 Aggregate 这样一个概念以及它是如何跟 POD(Plain Old Data)发生关联的?Aggregate 类型的类,可以被初始化通过 {},而non-Aggregate 的 class 不可以。(提出这样一个概念,是为了规范化初始化的用法):

struct X
{
    int i1;
    int i2;
};
struct Y
{
    char c;
    X x;
    int i[2];
    float f;
protected:
    static double d;
    Y& operator=(const Y& rhs) { return *this};
private:
    void g(){}
};

我们可直接使用{}进行初始化:

Y y = {'a', {10, 10}, {20, 30}};
            // y.c = 'a'
            // y.x.i1 = 10
            // y.x.i2 = 10
            // y.i[0] = 20
            // y.i[1] = 30
            // y.f = 0.0 by value-initialized 的方式
            // d 未被初始化,因为它是静态的

POD

来自C++标准:

A POD-struct is an aggregate class that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor. Similarly, a POD-union is an aggregate union that has no non-static data members of type non-POD-struct, non-POD-union (or array of such types) or reference, and has no user-defined copy assignment operator and no user-defined destructor. A POD class is a class that is either a POD-struct or a POD-union.
An aggregate class is called a POD if it has no user-defined copy-assignment operator and destructor and none of its nonstatic members is a non-POD class, array of non-POD, or a reference.

  • 所有的POD类都必须是Aggregate,或者说,一个类如果不是Aggregate,则一定不是POD类(两者成逆否命题)。

  • 和 Aggregates 的情况一样,静态成员不在乎其具体是什么样的类型(只要是静态的即可),

举个栗子:

struct POD
{
    int x;
    char y;
    void f() {};
                        // no harm if there's a function
    static std::vector<char> v;
                        // static members do not matter
};

struct AggregateButNotPOD1
{
    int x;
    ~AggregateButNotPOD1() {}
                // user-defined destructor
};

struct AggregateButNotPOD2
{
    AggregateButNotPOD1 arrOfNonPOD[3];
                // array of non-POD class
};
  • POD-classes are the closest to C structs. Unlike them, PODs can have member functions and arbitrary static members, but neither of these two change the memory layout of the object. So if you want to write a more or less portable dynamic library that can be used from C and even .NET, you should try to make all your exported functions take and return only parameters of POD-types.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Flink中的aggregate和reduce是不同的操作。aggregate是将多个输入元素转化为单个元素的操作,而reduce是将两个输入元素合并为一个元素的操作。区别在于,aggregate包含对多个元素的组合,而reduce只针对两个元素之间的组合操作。 ### 回答2: Flink是一个在大数据处理方面非常流行的流式数据处理引擎,它支持多种操作,其中Aggregate和Reduce是两种最常见的操作。Aggregate操作和Reduce操作在Flink中的使用和意义是不同的。 Aggregate操作是指对指定的Key中的元素进行聚合,将一个Key中的所有元素通过一个聚合函数进行计算,计算结果作为一个新的结果返回。主要特点是可以通过用户定义函数来实现聚合操作,同时还支持将结果中的Key和Value进行调换以满足不同的需求。这种操作主要适合于需要在数据流中计算一些汇总信息的场景。 Reduce操作与Aggregate操作的最根本区别在于其返回结果数据的格式,Reduce是将整个数据集合缩减成一个单一的结果型数据,而Aggregate则是对输入的Key进行聚合计算,返回与Key对应的结果型数据。 Reduce操作将输入数据流中的元素“归约”成一个结果元素,它将被发送到输出流中。 这种操作用于将具有相同关键字的元素合并为一个元素。Reduce操作在处理数据集和数据流时都很有用,因为它可以将数据分成不同部分,并将每个部分缩减为一个单一的结果以便后续处理。 总的来说,Flink的Aggregate操作和Reduce操作都是对数据流或数据集进行聚合计算的功能,只不过针对的数据集合和返回的结果型数据格式不同罢了。每种操作都有其适用的场景,在实际应用中应该根据需求进行选择。 ### 回答3: Flink是一个分布式流式处理引擎,其架构基于数据流而不是批处理。在Flink中,聚合操作是流式计算中最常用的操作之一。在聚合操作中,Flink提供了两种实现方式:Aggregate和Reduce。 Aggregate和Reduce都是聚合操作,它们都可以用于聚合输入数据流中的元素。Aggregate操作可以对输入的多个流元素进行转换,并将它们聚合成一个单一的输出元素。而Reduce操作只能聚合一个元素,并将多个元素转换为一个输出元素。 在Flink中,Aggregate和Reduce之间最显著的区别在于其并行处理能力。Aggregate操作可以实现并行聚合,因为它可以将输入流中的数据分成子流并在分布式环境中进行聚合。这意味着,Aggregate操作可以处理更大的数据文件,并利用更多的计算资源来加速数据处理。 相反,Reduce操作只能在一个流元素上执行聚合。因此,如果需要进行并行聚合处理,则需要使用Flink的keyed stream API来对输入数据流进行分区和分组。因为Reduce操作需要在同一分区中处理流元素,所以它只能使用单个计算资源来处理数据。 另外,Aggregate操作可以在窗口和时间点上进行聚合,因为它可以将输入数据流分组到窗口并在窗口中聚合多个元素。而Reduce操作只能在时间点上处理单个元素,因为它不能跨窗口进行聚合操作。 总而言之,Aggregate和Reduce都是Flink中常见的聚合操作。Aggregate操作可以用于流式计算的并行聚合和窗口聚合,而Reduce操作只能对单个流元素进行聚合操作。因此,在灵活性和可扩展性方面,Aggregate操作可能更优于Reduce操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五道口纳什

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值