C++ 聚合类(Aggregate Class)

2023-11-01

C++ 聚合类(Aggregate Class)

概述

该篇文章是用于梳理在学习聚合类的相关文章过程中总结归纳的相关知识点。用于后续深入理解和使用聚合类进行准备。

聚合类定义

首先看一下C++标准中的定义:

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).

由以上定义看出满足以下条件的类才可以称之为聚合类

  1. 无自定义构造函数;
  2. 非静态数据成员没有大括号或等号初始化器,即类内没有初始值;
  3. 无私有或保护的非静态成员;
  4. 无基类和虚函数。

下面我们举一个简单的例子进行说明:
我们可以提供一个花括号扩起来的成员初始值列表,并用它初始化聚合类的数据成员,初始值的顺序必须与声明的顺序一致,初始值列表的元素个数少于类的成员数量,则靠后的成员被值初始化。

struct Person
{
	std::string name;
	int height;
};

int main()
{
	Person person = {"xiaohong",10};
	std::cout << person.name<<" "<<person.height << std::endl;
	system("pause");
	return 0;
}

以下我们在例举一些典型的非聚合类和聚合类:

// 非聚合类
class NotAggregate1
{
  virtual void f() {} //定义了虚函数
};

class NotAggregate2
{
  int x; //定义了非静态的私有属性
};

class NotAggregate3
{
public:
  NotAggregate3(int) {} 自定义了构造函数
};

// 聚合类
class Aggregate1
{
public:
  NotAggregate1 member1;   //公共成员
  Aggregate1& operator=(Aggregate1 const & rhs) {/* */} //重载赋值运算符
private:
  void f() {} // 私有函数
};

聚合类的特性

聚合类的的主要特性是可以使用**{}**符号像数组一样进行初始化。
先从数据的初始化进行说明,数组初始化的形式如下:
Type array_name[n] = {a1, a2, …, am};

if (m == n)
	array_name的第i个元素由ai进行初始化
else if (m < n)
	前m个元素由1~m个a进行初始化,m-n个元素由'value-initialized'实现初始化
else if (m > n)
	编译器报错
else (类似数组定义形式: int a[] = {1, 2, 3};)
	数组的长度m = = n

value-initialized

下面解释一下什么是值初始化:
当一个标量类型(bool、int、char、double、pointers 等)的对象被值初始化时,这意味着它被初始化为 0 表示该类型(false 表示 bool,0.0 表示 double 等)。当具有用户声明的默认构造函数的类类型对象进行值初始化时,调用其默认构造函数。这个定义不精确,有点不正确,但它应该给你基本的概念。不能对引用进行值初始化。 例如,如果类没有合适的默认构造函数,则非聚合类的值初始化可能会失败。
下面例举一些典型例子,用于说明数组初始化:

class A
{
public:
  A(int) {} //无默认构造函数
};
class B
{
public:
  B() {} //默认构造函数
};
int main()
{
  A a1[3] = {A(2), A(1), A(14)}; //正常 n == m
  A a2[3] = {A(2)}; //错误 类A没有默认构造函数. 无法对a2[1]和a2[2]进行值初始化
  B b1[3] = {B()}; //正常 b1[1]和b1[2]可以通过默认构造函数进行值初始化
  int Array1[1000] = {0}; //所有元素初始化为0;
  int Array2[1000] = {1}; //第一个元素初始化为1,其它全部为0;
  bool Array3[1000] = {}; //所有的值被初始化为false
  int Array4[1000]; //没有初始化,数组元素都是不确定的值;
  int array[2] = {1, 2, 3, 4}; //错误, 初始化值个数大于数组长度
}

聚合类的初始化方法

现在让我们看看如何用大括号初始化聚合类。几乎和数组的值初始化相同的方式。我们将按照在类定义中出现的顺序初始化非静态数据成员(根据定义,它们都是公共的)。如果初始化器比成员少,则其余的都是值初始化的。如果初始值设定项少于成员数,则其余的都是值初始化的。如果无法对未显式初始化的成员之一进行值初始化(如数据类型不匹配),则会出现编译时错误。如果初始值设定项过多,我们也会收到编译时错误。
如下面代码中所示:

struct X
{
  int i1;
  int i2;
};
struct Y
{
  char c;
  X x;
  int i[2];
  float f; 
protected:
  static double d;
private:
  void g(){}      
}; 

Y y = {'a', {10, 20}, {20, 30}};

在上面的例子中y.c用’a’初始化,y.x.i1用10,y.x.i2用20,y.i[0]用20,y.i[1]用30和y.f是值初始化的,即用0.0初始化。 受保护的静态成员 d 根本没有初始化,因为它是静态的。

union(聚合)

聚合联合的不同之处在于,可以只用大括号初始化它们的第一个成员。如果在 C++ 方面足够先进,甚至可以考虑使用联合(它们的使用可能非常危险,必须仔细考虑。

总结

现在我们知道了聚合的特别之处,让我们尝试了解对类的限制; 也就是说,他们为什么在那里。 我们应该明白,带大括号的成员初始化意味着该类只不过是其成员的总和。如果存在用户定义的构造函数,则意味着用户需要做一些额外的工作来初始化成员,因此大括号初始化将是不正确的。如果存在虚函数,则意味着该类的对象(在大多数实现中)具有指向该类的所谓 vtable 的指针,该指针是在构造函数中设置的,因此大括号初始化是不够的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 聚合类(Aggregate Class) 的相关文章

  • CLR 2.0 与 4.0 性能比较?

    如果在 CLR 4 0 下运行 为 CLR 2 0 编译的 NET 程序会运行得更快吗 应用程序配置
  • 计算 XML 中特定 XML 节点的数量

    请参阅此 XML
  • 适合初学者的良好调试器教程[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有谁知道一个好的初学者教程 在 C 中使用调试器 我感觉自己好像错过了很多 我知道怎么做 单步执行代码并查看局部变量 虽然这常常给我带来问
  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • 代码 GetAsyncKeyState(VK_SHIFT) & 0x8000 中的这些数字是什么?它们是必不可少的吗?

    我试图在按下按键的简单动作中找到这些数字及其含义的任何逻辑解释 GetAsyncKeyState VK SHIFT 0x8000 可以使用哪些其他值来代替0x8000它们与按键有什么关系 GetAsyncKeyState 根据文档返回 如果
  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • JNI 将 Char* 2D 数组传递给 JAVA 代码

    我想从 C 代码通过 JNI 层传递以下指针数组 char result MAXTEST MAXRESPONSE 12 12 8 3 29 70 5 2 42 42 在java代码中我写了以下声明 public static native
  • 识别 Visual Studio 中的重载运算符 (c++)

    有没有办法使用 Visual Studio 快速直观地识别 C 中的重载运算符 在我看来 C 中的一大问题是不知道您正在使用的运算符是否已重载 Visual Studio 或某些第三方工具中是否有某些功能可以自动突出显示重载运算符或对重载运
  • 打破 ReadFile() 阻塞 - 命名管道 (Windows API)

    为了简化 这是一种命名管道服务器正在等待命名管道客户端写入管道的情况 使用 WriteFile 阻塞的 Windows API 是 ReadFile 服务器已创建启用阻塞的同步管道 无重叠 I O 客户端已连接 现在服务器正在等待一些数据
  • 在mysql连接字符串中添加应用程序名称/程序名称[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在寻找一种解决方案 在连接字符串中添加应用程序名称或程序名称 以便它在 MySQL Workbench 中的 客户端连接 下可见 SQL
  • 等待 IAsyncResult 函数直至完成

    我需要创建等待 IAsyncResult 方法完成的机制 我怎样才能做到这一点 IAsyncResult result contactGroupServices BeginDeleteContact contactToRemove Uri
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • 将数组作为参数传递

    如果我们修改作为方法内参数传递的数组的内容 则修改是在参数的副本而不是原始参数上完成的 因此结果不可见 当我们调用具有引用类型参数的方法时 会发生什么过程 这是我想问的代码示例 using System namespace Value Re
  • 在 Windows Phone silverlight 8.1 上接收 WNS 推送通知

    我有 Windows Phone 8 1 silverlight 应用程序 我想使用新框架 WNS 接收通知 我在 package appxmanifest 中有
  • 可访问性不一致:参数类型的可访问性低于方法

    我试图在两个表单之间传递一个对象 基本上是对当前登录用户的引用 目前 我在登录表单中有一些类似的内容 private ACTInterface oActInterface public void button1 Click object s
  • 如何减少具有多个单元的 PdfPTable 的内存消耗

    我正在使用 ITextSharp 创建一个 PDF 它由单个 PdfTable 组成 不幸的是 对于特定的数据集 由于创建了大量 PdfPCell 我遇到了内存不足异常 我已经分析了内存使用情况 我有近百万个单元格的 1 2 在这种情况下有
  • 如何使用 C++11 using 语法键入定义函数指针?

    我想写这个 typedef void FunctionPtr using using 我该怎么做呢 它具有类似的语法 只不过您从指针中删除了标识符 using FunctionPtr void 这是一个Example http ideone
  • OpenCV SIFT 描述符关键点半径

    我正在深入研究OpenCV的SIFT描述符提取的实现 https github com Itseez opencv blob master modules nonfree src sift cpp 我发现了一些令人费解的代码来获取兴趣点邻域

随机推荐

  • 极限的运算法则

    极限的运算法则 两个无穷小的和也是无穷小 定理 有限个无穷小的和也是无穷小 无穷多个无穷小的和是1 定理 有界函数与无穷小的乘机也是无穷小 推论 常数与无穷小的乘积也是无穷小 推论 有限个无穷小的乘积也是无穷小 无限多个无穷小的乘积不一定是
  • 解决eclipse突然打不开了的问题

    网上搜了有大概六种 我又get一个解决方案 找到属于自己的方案才是关键 解决方式 7种 1 通过在命令行中输入 where java 找到除jdk目录下的所有java相关程序 直接删掉 一般会在C WINDOWS system32下 2 内
  • SQL刷题:SQL必知必会

    MySQL函数参考教程 1 多字段排序用逗号隔开 对多个字段排序的时候 同样满足默认ASC select cust id order num from Orders order by cust id order date desc sele
  • PicGo使用阿里云OSS配置图床

    PicGo使用阿里云OSS配置图床 前言 安装 PicGo PicGo molunerfinn com 以上是PIcGo的配置阿里云OSS需要的值 1 阿里云创建用户 登录阿里云 鼠标移到头像位置则可看到 点击访问控制 创建新用户 开启op
  • 摩拜单车红包骑行引发的潮汐问题思考

    前言 摩拜刚刚推行红包骑行的时候写的 最近比较忙一直忘记了 今天有时间发出来 言语不当之处 还望见谅 希望各位发表意见 谢谢 PS 摩拜单车相关人员已经看过 表示还可以 谢谢 2017 年 共享单车有很多 最先进入人们眼帘的应该是那一个类似
  • Part 5:Pandas 数据统计函数【汇总类统计、唯一去重和按值计数、相关系数和协方差】

    Pandas 数据统计函数 1 汇总类统计 2 唯一去重和按值计数 3 相关系数和协方差 import pandas as pd 1 预备步骤 对数据进行读取和预处理 将温度都改为Int类型 fpath datas beijing tian
  • jquery正则表达式写法

    const FloatRegex 0 9a zA Z 1 if FloatRegex test value this message error 只能输入数字 字母 下划线 小圆点 return
  • 计算机基础知识总结

    文章目录 1 Linux常用基本命令 文件管理 用户管理 进程管理 软件仓库搭建 远程登陆服务器 文件传输 定时任务 延迟任务 2 C 基础知识 面向对象的四大特征 C 和C语言有什么不同 new delete 和 malloc free
  • 【翻译】API版本管理:它是什么,为什么这么难?

    如果你想在API技术专家之间展开一场辩论 只要让他们分享他们对 API版本 的看法 可以肯定的是 你会在短时间内发现一些强烈的感受 术语 API版本 已经成为 改变API 的同义词 这是理清支持已发布的API持续变化而又不给API消费者带来
  • java中方法名,对象名,变量名,标识符,关键字的规则

    java中方法名 对象名 变量名 标识符 关键字的规则 总绪 方法名 对象名 变量名 标识符 关键字 总绪 所有命名规则必须遵循以下规则 1 名称只能由字母 数字 下划线 符号组成 2 不能以数字开头 3 名称不能使用JAVA中的关键字 4
  • 机试之前最后的知识点总结。

    题目描述 C 头文件大全 解题思路一 include
  • 敏捷Agile: Epic vs UserStory vs Task

    Epic Story Task Epic Epic是User Story逻辑上的集合 一个Epic可以被break down成多个小的User Story 一个Epic可能需要多个Sprint才能完成 User Story vs Task
  • TensorFlow各版本下载地址

    TensorFlow各版本自主下载地址 cpu版本 pip install 链接 https pypi python org pypi tensorflow 2 0 0 下载地址链接 https pypi org project tenso
  • MATLAB实现基本的PSO粒子群算法优化目标函数(求函数最小值的解),写成函数的形式,并举例演示如何使用

    粒子群优化算法 Particle Swarm Optimization 是一种进化计算机技术 evolutionary computation 源于对鸟类捕食行为的研究 是一种基于迭代的优化工具 事实上 像PSO这种同属于元启发式优化算法有
  • java中静态代码块详解

    今天在项目中看到这行代码 静态代码块 很久没用静态代码块了 今天来复习一下 依旧按照为什么 是什么 怎么用 的思想 去学习 为什么 先说说代码中为什么要使用这种写法吧 还记得静态代码块的特点吗 随着类的加载而执行 而且只执行一次 对 没错
  • 求求你们了,MyBatis 批量插入别再乱用 foreach 了,5000 条数据花了 14 分钟。。...

    近日 项目中有一个耗时较长的Job存在CPU占用过高的问题 经排查发现 主要时间消耗在往MyBatis中批量插入数据 mapper configuration是用foreach循环做的 差不多是这样 由于项目保密 以下代码均为自己手写的de
  • Windows获取CPU、内存和磁盘使用率脚本

    获取CPU使用率脚本 vbs 另存为cpu vbs On Error Resume Next Set objProc GetObject winmgmts root cimv2 win32 processor cpu0 Wscript Ec
  • C语言:输出1000~3000年中所有的闰年,每5年换一行

    C语言 输出1000 3000年中所有的闰年 每5年换一行 题目 分析 代码 题目 编写程序 输出1000 3000年中所有的闰年 每5年换一行 分析 判断闰年的条件为 能被4整除但不能被100整除 或者能被400整除 代码 include
  • 《Vision Transformers: State of the Art and Research Challenges》论文翻译阅读

    作者 Bo Kai Ruan Hong Han Shuai Wen Huang Cheng 概要 Transforme在自然语言处理中取得了巨大的成功 由于Transformer的自注意机制具有强大的能力 研究人员开发vision tran
  • C++ 聚合类(Aggregate Class)

    C 聚合类 Aggregate Class 文章目录 C 聚合类 Aggregate Class 概述 聚合类定义 聚合类的特性 value initialized 聚合类的初始化方法 union 聚合 总结 概述 该篇文章是用于梳理在学习