C++初学者指南第一步---13.聚合类型

C++初学者指南第一步—13.聚合类型

文章目录

  • C++初学者指南第一步---13.聚合类型
    • 1. 类型分类(简化)
    • 2. 如何定义和使用
    • 3. 为什么选择自定义类型/数据聚合?
    • 4. 聚合类型初始化
    • 5.混合
    • 6. 复制
    • 7. 值和引用的语义
    • 8.聚合的向量(std::vector)
    • 9.最令人烦恼的解析

1. 类型分类(简化)

基本类型void, bool, char, int, double, …
void、bool、char、int、double、…
简单聚合主要用途:对数据进行分组
聚合:可能包含一个/多个基本类型或其他兼容的聚合类型
无法控制组成类型的相互作用
简单,(编译器生成的)默认构造/析构/复制/赋值。
标准的内存布局(所有成员按照声明顺序连续布置),如果所有成员具有相同的访问控制(例如全部为public)。
更复杂的自定义类型自定义不变量和对成员相互作用的控制
限制成员访问
具有成员函数
用户自定义构造/成员初始化
用户自定义的析构 / 复制 / 赋值
可以是多态的(包含虚成员函数)

2. 如何定义和使用

示例:具有 2 个整数坐标的类型
代码段1

struct point {
  int x;  // ← "成员变量"
  int y; 
};
// 创建新对象 (在栈中)
point p {44, 55}; 
// 打印成员变量的值
cout << p.x <<' '<< p.y;  // 44 55

分配给成员变量值:(代码段2)

p.x = 10;
p.y = 20;
cout << p.x <<' '<< p.y;  // 10 20

成员变量的存储顺序与声明顺序相同。
代码段1的内存:
在这里插入图片描述
代码段2的内存:
在这里插入图片描述
运行上面代码

3. 为什么选择自定义类型/数据聚合?

接口变得更易于正确使用

  • 语义数据分组: 点,日期…
  • 避免了许多函数参数,从而减少了混乱。
  • 函数可以使用一个专门的类型来返回多个值,而不是使用多个非常量引用输出参数。

不使用则会有糟糕的接口:

void closest_point_on_line (double lx2, double ly1, double lx2i, double ly2, double px, double py, double& cpx, double& cpy) { … }
  • 许多相同类型的参数⇒容易编写错误
  • 非常量引用输出参数 ⇒ 容易出错
  • 线的内部表示也被嵌入到接口中

使用则好多了:

struct point { double x; double y; };
struct line  { point a; point b; };
point closest_point_on_line (line const& l, point const& p) { … }
  • 直接明了的接口
  • 易于正确使用
  • 如果线的内部表示更改了(例如,点+方向而不是2个点)⇒ 需要改变closest_point_on_line的实现方式,但其接口可以保持不变⇒ 大多数调用代码无需更改!

4. 聚合类型初始化

语法:

Type { arg1, arg2, …, argN }
  • 花括号括起来的成员值列表
  • 按成员声明顺序排列
enum class month {jan = 1, feb = 2,…, dec = 12};
struct date {
  int yyyy;
  month mm;
  int dd;
};
int main () {
  date today {2020, month::mar, 15};	
  // C++98的写法,依然正确:
  date tomorrow = {2020, month::mar, 16};	
}

5.混合

示例:作为 person 成员的日期

enum class month { jan=1, feb=2,, dec=12 };
struct date {   
  int yyyy;
  month mm;
  int dd;
};
struct person {
  std::string name;
  date bday;
};
int main () {
  person jlp { "Jean-Luc Picard", {2305, month::jul, 13} };
  cout << jlp.name;     // Jean-Luc Picard
  cout << jlp.bday.dd;  // 13
  date yesterday { 2020, month::jun, 16 };
  person rv = { "Ronald Villiers", yesterday };
}

运行上面代码

6. 复制

副本总是所有成员的深层拷贝!

enum class month {jan = 1,};
struct date { 
  int yyyy;  month mm;  int dd; 
};
int main () {
  date a {2020, month::mar, 7};     
  date b = a;  // deep copy of a
  b.dd = 22;   // change b
}

main 函数最后一行后的状态:
在这里插入图片描述
拷贝构造 = 创建一个具有与源相同值的新对象
拷贝赋值 = 使用源对象的值覆盖现有对象的值

struct point { int x; int y; };
point p1 {1, 2};  // 构造
point p2 = p1;    // 拷贝构造
point p3 ( p1 );  // 拷贝构造
point p4 { p1 };  // 拷贝构造
auto  p5 = p1;    // 拷贝构造
auto  p6 ( p1 );  // 拷贝构造
auto  p7 { p1 };  // 拷贝构造
p3 = p2;  // 拷贝赋值
          // (p2和p3之前都存在)

7. 值和引用的语义

值语义
= 变量是指对象本身:

  • 深拷贝:生成一个新的、独立的对象;对象(成员)的值被复制。
  • 深度赋值:使目标的值等于源对象的值。
  • 深度所有权:成员变量引用与包含对象生命周期相同的对象。
  • 基于值的比较:如果它们的值相等,则变量相等。

值语义是几乎所有编程语言中基本类型(int、double等)的默认行为,也是C++中聚合类型/用户自定义类型的默认行为。

引用语义
= 变量是对对象的引用:

  • 浅层复制:变量的副本引用同一对象。
  • 浅层赋值:赋值使变量引用不同的对象。
  • 浅层所有权:成员变量也只是引用。
  • 基于身份的比较:如果变量引用同一对象,则比较相等。

大多数其他主流语言(Java、Python、C#、Swift 等) 对用户自定义类型使用(内置)引用语义。
C++ 的情况是一致的,能够提供全面的控制:

  • 默认情况下:所有类型都采用值语义(除了C风格数组)。
  • 所有类型都可以使用可选的引用语义(通过引用或指针)来实现。

8.聚合的向量(std::vector)

值语义 ⇒

  • vector 的存储包含类型 T 的对象本身,而不仅仅是对它们的引用或指针(就像在 Java/C#/… 中一样)。
  • 如果向量对象被释放 ⇒ 包含的 T 对象也会被释放。
vector v { 0,1,2,3,4 };在这里插入图片描述
struct p2d { int x; int y; };
vector v {{1,2},{5,6},{8,9}};
在这里插入图片描述

9.最令人烦恼的解析

无法使用空括号进行对象构造,因为在C++语法中存在歧义。
在这里插入图片描述

struct A { ... };
A a();  // 声明了一个函数 'a'
        // 没有参数
        // 返回类型为 'A'
A a;    // 构造了一个 A 类型的对象
A a{}  // 也构造了一个 A 类型的对象

附上原文地址
如果文章对您有用,请随手点个赞,谢谢!^_^

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/735837.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

文件创建与查看

touch touch命令用于创建一个新的文件。 语法&#xff1a;touch Linux路径 其中路径可以是相对路径、绝对路径或者特殊路径符都可以。 改图展示了通过 touch test.txt 命令创建了一个 test.txt文件&#xff0c;其中深色的代表文件夹&#xff0c;白色的代表文件。 使用 ls -lh…

React学习(二)——状态(数据)与状态修改

useState 在React中&#xff0c;useState 是一个非常重要的Hook&#xff0c;它允许你在函数组件中添加“状态”&#xff08;state&#xff09;。在传统的React类组件中&#xff0c;我们使用this.state来管理和更新组件的状态。然而&#xff0c;在函数组件中&#xff0c;由于它们…

一个关于空格的Sql Server面试题

引子 先上题目&#xff1a; 回答下面sql 的输出结果 declare s1 varchar(10) declare s2 varchar(10) set s1a b set s2a b if s1s2 select true 答案是 true 那么上面的 s1 和 s2 是否相等的呢&#xff1f; 我们再看看下面的sql declare s1 varchar(10) declare s2 …

鞋子分类数据集17399张69类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;17399 分类类别数&#xff1a;69 类别名称:[“0”,“1”,“2”,“3”,“4”…

计组_指令的执行过程

2024.06.19&#xff1a;计算机组成原理指令的执行过程学习笔记 第18节 指令的执行过程 8.1 指令周期8.2 指令的执行过程8.2.1 取指令8.2.2 译码8.2.3 根据源操作地址计算并取操作数8.2.4 执行数据操作8.2.5 目的操作数地址计算并存结果 8.3 指令的数据流8.3.1 取值周期的数据流…

切换国内yum源

切换国内yum源 一、备份现有YUM源二、下载新的YUM源配置文件三、先清理YUM缓存再生成四、测试新的YUM源五、重启系统服务(生效可以不重启)可选 首先&#xff0c;切换国内YUM源的具体步骤取决于您使用的Linux发行版和当前的YUM源配置。以下是一般步骤&#xff0c;适用于大多数基…

CSS基础学习记录(5)

目录 1、CSS语法 2、实例 3、CSS注释 4、id 选择器 5、class 类选择器 6、标签选择器 7、内联选择器 1、CSS语法 CSS 规则由两个主要的部分构成&#xff1a;选择器&#xff0c;以及一条或多条声明: 选择器&#xff08;Selector&#xff09;通常是您需要改变样式的 HTML …

【机器学习300问】125、什么是双向循环神经网络(BRNN)?什么是深度循环神经网络(DRNN)?

一、双向循环神经网络 &#xff08;1&#xff09;诞生背景 双向循环神经网络&#xff08;Bidirectional Recurrenct Neural Network, BRNN&#xff09;是在深度学习领域发展起来的一种特殊类型的循环神经网络&#xff08;RNN&#xff09;&#xff0c;它诞生的背景是为了解决传…

烧结刚玉砂轮片 CBN砂轮 氮化硼砂轮 磨具用晶谷低温陶瓷结合剂玻璃粉

晶谷烧结刚玉砂轮低温陶瓷结合剂玻璃粉具有以下特点&#xff1a; - 软化点&#xff1a;软化点在450至650度之间。 - 热膨胀系数&#xff1a;热膨胀系数为&#xff08;50至120&#xff09;10-7。 - 粒径&#xff1a;粒径为300至3000目&#xff0c;可按要求订做。 - 外观颜色&a…

sudo 权限之危险的 bash 命令

文章目录 [toc]事出有因干就完事了创建用户配置 sudo 权限sudo 验证使用 bash 命令执行 chmod 命令使用 bash 命令执行删根 事出有因 使用普通用户安装 tidb 时&#xff0c;发现报错了&#xff0c;报错内容如下&#xff1a; ERROR SSHCommand {"host": "…

硕思闪客精灵软件安装包下载+详细安装教程

​有目共睹的是闪客精灵专业版的优势&#xff1a;能够安装一台电脑&#xff0c;终身免费升级。根据大数据结果显示闪客精灵支持将不带脚本的Flex生成的SWF导出为Flex文件。从大部分从业者反应来看它能反编译Flash的所有元素,并且支持动作脚本 AS3.0&#xff0c;使用闪客精灵专业…

python rename报错怎么解决

刚接触python&#xff0c;写了一段简单的代码&#xff0c;功能就是重命名一个文件&#xff0c;代码如下&#xff1a; list_1os.listdir(".") for files in list_1:fopen(files)if f.name"01.txt":os.rename(01.txt,001.txt)elif f.name"05.txt":…

AI 大模型应用开发实战(04)-AI生态产业拆解

1 行业全景图 2 结构拆解AI GC 生成式AI这个产业。分成上中下游三大块。 2.1 上游基础层 主要包括&#xff1a; 算力&#xff1a;包括AI芯片和云服务等&#xff0c;例如像英伟达、AMD以及华为等厂商提供的算力基础设施。大型模型基于Transformer架构&#xff0c;对算力的需…

【Sklearn驯化-环境配置】一文搞懂sklearn建模的最优环境搭建用法

【Sklearn驯化-环境配置】一文搞懂sklearn建模的最优环境搭建用法 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 相关内容文档获取 微信…

CARLA自动驾驶模拟器基础

CARLA 使用服务器-客户端架构运行&#xff0c;其中 CARLA 服务器运行模拟并由客户端向其发送指令。客户端代码使用 API 与服务器进行通信。要使用 Python API&#xff0c;您必须通过 PIP 安装该模块&#xff1a; pip3 install carla-simulator # Python 3World and client 客…

【职场人】如何与同事有效沟通

在职场中&#xff0c;沟通如同桥梁&#xff0c;连接着每一位职场人士的心灵与智慧。有效的沟通不仅能让工作更加顺畅&#xff0c;还能让团队关系更加和谐。那么&#xff0c;如何与同事进行有效沟通呢&#xff1f;下面&#xff0c;我将结合个人经验和一些幽默的比喻&#xff0c;…

Python的pip切换国内源

&#x1f4da;目录 起因&#xff1a;pip切换国内源&#xff1a;操作永久修改pip配置文件测试永久源配置是否成功 pip其他环境的配置永久源配置 起因&#xff1a; pyCharm安装模块的手出现ModuleNotFoundError: No module named distutils 由于使用pip install distutils下载不了…

绘制口罩maskTheFace数据源是300w_lp

官网下载mask the face 代码&#xff0c;增加代码draw_face.py import argparse import cv2 import scipy.io from tqdm import tqdm from utils.aux_functions_2 import *# 设置命令行输入参数 parser argparse.ArgumentParser(description"MaskTheFace - Python code…

用腾讯云语音合成(TTS)批量生成英语绘本的朗读音频

孩子进行英语启蒙&#xff0c;需要看很多英语绘本&#xff0c;而且要听配套的音频来练听力。但有些英语绘本是没有对应音频的&#xff0c;下面简单几步&#xff0c;就可以将任意英语绘本制作出对应的英语朗读音频。 先到电子书资源网站搜索这个绘本名称&#xff0c;如果有电子…

C++学习合集

#整理到一块&#xff0c;方便查东西&#xff0c;顺便补充一些之前没有学习到的东西# 变量 char--1字节 short--2字节 int-4字节 long--4字节 long long(int)--8字节&#xff1b;准确来说变量的大小取决于编译器&#xff0c;1字节8个二进制位&#xff0c;其中最高位为符号位…