C++ 具名要求:aggregate(聚类),PODs->>(trivial(-ly copyable),standard lauout)

(由于简书目前不支持[toc]无法快速生成目录,所以可能看起来会有点长。)
这篇文章的参考处:
https://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special


概述

本段分三个部分讲,从最开始的C++03一直到目前的C++17。
首先要明白一个从属关系和这两个概念的基本:
聚类是PODs的一个超集,即如果一个class(在标准中,术语class代表了class,struct,union)是PODs,那么这个类就必为聚类,但是如果一个class是聚类,这个class不一定是一个PODs。
那么首先要明白的是,聚类的一个最明显的特性,一个聚类要求,其本身实例的结构和内部定义的结构一致,即和C中的struct一样,其实实际上是异常相似,里面的成员是什么,那么相应一个实例的内部构造就是这些东西组成的,并且要求以上说道的这些成员是语法可见的


开始正题:

C++03

一、

一个聚类由本身特性可知,聚类是不可能有多态的,因为如果存在,则必须在实例内保留一个指针指向虚表以确定正确执行当前实例动态类型的函数

二、

以任意访问限定存在的成员函数,静态数据成员都是允许的,因为以上两者不会影响对象实例的内部结构

三、

聚类不能有用户定义的任何形式的构造函数(以下统称构造函数),即移动,拷贝,构造,等,(下面是C++11的内容扩展)但是用户可以显示指定出来,即显示说明构造函数的访问限定(在构造函数后加=default)


以上是PODs和聚类相同的地方。

不同的地方有:


一、

聚类可以有用户定义的复制函数,析构函数

二、

聚类的非静态成员可以是非PODs的类型(包括数组,只要是一个数组,就是一个聚类)


PODs

一、

PODs要求,用户不能自定义复制函数,析构函数,并且非静态成员成员必须在满足聚类前提下不能是非PODs类型,以及引用类型


以上是C++03的聚类和POD的定义,下面来看一下特点,示例请在https://github.com/KinoluKaslana/CPPLearning/blob/master/Aggregate_and_PODs.cpp中查看

首先是聚类

一、

从数组说起,其初始化可以通过一个{}进行初始化(即进行显式初始化),当initlizer_list中的数量等于数组容量时,将对其进行等值拷贝,如果存在小于的情况,那么其余没有被值包括到的数据就会被按照默认的初始化方式进行初始化,对于表两类型,其会被初始化为0,对于成员类元素则是调用其默认构造函数,但是如果成员是引用,则无法对其进行默认初始化

二、

对于其他的聚类也一样可以通过一对{}将其成员数据直接初始化,没有被包括的则按照默认初始化,如果类数据成员和引用不存在直接初始化数据(对于类数据则需要传入相应构造函数的数据格式)则会抛出错误

注意,以上显示初始化并不走任何的构造函数

C++11

C++11较C++03

一、

对聚类的变化不大,只是对C++11中的新特性——在定义时类成员初始化做了限制,当一个类,存在非静态的类内成员初始化,那么这个类就不是一个聚类

二、

对描述:不能有用户声明的构造函数;改为->不能有用户提供功能的构造函数
但是对于POD则进行了极大的改动,并且将其拆为了两个更加实用的两个类:
trivial和standard layout


trivial:

要了解这个类,就必须了解什么是trivial和non-trivial
如果一个类型符合以下规定:

一、

没有用户提供的析构,复制,移动构造函数(赋值运算符),允许继承或被继承但没有虚函数,虚基类

二、

对于所有的数据成员,基类数据成员,作为数据成员的数组的元素类型,必须递归的满足上述条件

三、

对于构造函数,则同样满足之前Aggregate的规则同样也不能存在非静态数据成员的花括号,等号的初始化。

四、

对于析构函数,也满足不能是虚函数条件


那么这个类型就是一个trivial copyable的类型

所有的平凡约定,均代表,默认,即非用户提供的


注意:

一)

trivially copyable是trivial的超集,前者不对默认构造函数有要求,后者对默认构造函数有要求,但是不对其他非移动,复制的构造之外的构造函数有限制。

二)

对于standard layout 的类,不对任何构造函数,析构函数,复制、移动的构造函数,复制、移动的复制运算符做要求,同时,只要求所有的非静态数据成员不为非standard layout类型,和标量类型,同时不能有虚基类,虚函数,多继承是被允许的,对于所有的数据成员,并不做任何访问限制要求,唯一的规定是所有的数据成员必须是同一个访问限制的。

注意:

由于trivially copyable是不对任何默认构造函数有要求的,所以单独只能在trivially copyable以及std layout中使用member interlized对POD系成员进行初始化。

C++14

C++14中仅仅对aggregate做了一个小修改:

一、

允许使用成员初始化。


那么到现在各部分的定义就为:

aggregate:

一、

不允许当前将被定义为aggregate的类(以下称之为该类)在任何位置存在任何虚函数。

二、

该类不允许出现非public的非静态成员

三、

成员函数可以为任意访问限定

四、

不允许有用户提供的构造函数,但是允许有用户提供的重载赋值运算符,析构函数,同样,这一条定义也必须符合前几条的规定

五、

允许基类,非静态数据成员为任意类型,即非aggregate的都可以,并且允许其有成员初始化。

trivial

trivially cpoyable

如果一个类是trivially copyable的话,则需要遵守以下规则:

一、

不允许出现非trivial(即用户提供的)复制、移动构造,重载赋值运算符,析构函数

二、

其可以继承,但不允许出现虚基类,虚函数

所有的非静态数据成员,基类必须递归满足上述条件即trivially copyable的

trivial

如果一个类是trivial的话,需要遵守以下规则:

一、

必须满足所有的trivially copyable的规定

二、

默认构造函数必须为平凡,即不允许出现成员初始化。

三、

对所有的trivial成员,基类,必须递归满足上述两条。

standard layout

如果一个类是standard layout的话,需要遵守以下规则:

一、

所有的非静态数据成员必须是同一个访问限定,并且不能是非standard layout的,同时第一个非静态数据成员不能是基类类型

二、

不能有虚基类,虚函数。

三、

继承树上,只允许有一成员存在非静态数据成员

四、

对于所有基类,数据成员递归检测上述约定不能存在菱形继承。

C++17:

aggregate

一、

在C++14的基础上,允许aggregate存在继承,但是继承必须是非虚,非private,protected,并不强制要求基类为aggregate

二、

不允许存在继承构造,explicit的构造函数

三、

如果成员,基类为非aggregate那么他们仍然是list-initialized,此时调用的是相应参数的构造函数,如果不存在,则抛出错误。

trivial

trivially copyable:

对C++14中明确规定的必须包含非trivial的复制,移动构造,运算符重载进行重申——一个要求为trivial的类至少包含一个为非删除的其中以上的所有函数,并且必须包含一个trivial的非析构函数,对于其成员类型,以上函数被声明为删除是会影响当前类的trivially copyable的特性的。

trivial:

同上,在满足上述trivially copyable的情况下,也必须包含一个trivial的,非删除的默认构造函数

standard layout:

C++17对standard layout的继承,有了更加严格的定义:

一、

当存在第一个数据成员为以下类型时,其对应的基类类型不能是:

二、

数据成员为X,其不含有非静态数据成员,那么基类类型的限制集为空集

三、

数据成员为X,其中第一个非静态数据成员类型为X0(有可能是一个匿名union)那么此时基类的限制类型为X0和其X0的元素(如果存在的话)组成

四、

数据成员为X,X是一个union,那么基类限制集为X中所有的类型,并且对其union的类型的成员进行递归本定义的所有条款。

五、

数据成员为X,X是类型为X1的数组那么集合为X1和X1的类型集合组成,该条规定递归本定义中所有条款

六、

数据成员不X,为类,不为数组类型,那么集合为空。

注意,所有条款中,出现子类型的均对其子类型递归执行上述所有条款。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,288评论 0 10
  • 鸟儿低低的飞着 翅膀碰落了尘埃 阳光照着叶子 柿子树在天空的倒影里做着开花的梦 叶子碰着叶子 孤独被赶进瓦蓝的云里...
    南河沙阅读 353评论 3 22
  • 从此我不再写诗了去做一个安安分分的过客去和海子一样劈柴挑水去那无人知晓的天涯海角这个时代神魔乱舞这个时代不适合老实...
    守海入梦阅读 907评论 25 23
  • 言良子阅读 304评论 0 0
  • 今日练习内容,唐诗五首:王维《杂诗》(其二)、祖咏《终南望馀雪》、裴迪《送崔九》、孟浩然《宿建德江》、孟浩然《春晓》。
    甜蜜荔枝阅读 240评论 0 4