当前位置: 首页 > news >正文

2310C++构造对象

原文

本文展示一个构造对象方式,用户无需显式调用构造器.对有参构造器类,该实现在构造改对象时传递默认值来构造.
当然用户也可指定(绑定)某个参数的值.实现思路参考boost-ext/di的实现.看下示例:

构 成员{整 x=10;
};
构 成员1{整 x=11;
};
类 例子1{:例子1(成员 x,成员1 x1){输出<<x.x<<行尾;//10输出<<x1.x<<行尾;//11}
};
整 主(){动 e1=远前::对象创建者<>().元 创建<例子1>();
}

示例比较简单,构造一个对象创建者对象,并调用他的创建来创建一个例子1的对象,因为使用对象创建者来构造,所以不需要传递参数,它会自动构造.

好处是,构造对象时,可无需考虑该对象构造器几个参数或类型,想要增加参数时,无需修改代码,当然指定参数的话除外.
该用法也叫依赖注入.

构思主体实现

还蛮酷炫,看看如何做到的?先来说下主体想法,首先最重要的当然是对象创建者,该类如何知道要构造对象的构造器参数类型是什么呢,知道参数类型才能构造一个参数传递,同时参数也同样需要对象创建者来构造,依次递归.

上边说到了有两个问题要解决,第一个就是如何识别构造器的参数类型,第二个是要构造构造器参数时,如果递归构造?

识别构造器参数类型

使用任何类型来识别构造器参数,简单示例:

构 任何类型{<型名 T>符号 T(){中 T{};}
};
构 成员{};
构 例子{例子(成员 m,){}
};
整 主(){例子(任何类型(),2);0;
}

调用任何类型()可匹配至任意类型,然后在构造例子时,编译器会去找相应类型来构造.大家可能发现我使用的是多个参数来举例任何类型,如果参数是单个任何类型会有冲突,因为拷贝构造器也是一个参数,所以编译器会识别冲突,该问题后边也要处理.

类 例子{:例子(成员 m){输出<<m.x<<行尾;}
};
整 主(){例子 e(任何类型{});0;
}
//--------以下报错
注意:候选人:'例子::例子(成员)'
|例子(成员 m){
|^~~~~~~
:注意:候选人:'常式 例子::例子(常 例子&)'
类 例子{

递归构造构造器的参数

因为构造器参数可能是个类对象,该对象的构造器参数又是其他类对象,识别类型后,继续调用函数来构造该对象,以此类推.

保存绑定参数

当然使用过程也不全部是使用默认构造,可能也需要传递指定参数与构造器参数绑定,但是构造器的参数类型又是多样的.

这里先用元组来保存,若识别出来的类型保存数据类型是一致的,则不用构造而是直接传递该数据给构造器.

代码实现

开始写代码,肯定有个任何类型的类及对象创建者的类.对象创建者用来构造对象返回,会只用任何类型类来识别类型.

对象创建者

大概看下具体的实现:

<型名...O>
类 对象创建者{:<型名...T>显 对象创建者(T&&...o):依赖_(前向<T>(o)...){}
//...:元组<常 O&...>依赖_;
};

元组保存要绑定参数时,要保存数据就得拷贝,这里为了避免拷贝,元组中类型是左引用,但这样就得用户自己来维护要绑定参数的生命期.

O是要绑定参数类型,构造器中为了避免拷贝,用完美转发来实现.依赖_就是保存绑定参数数据结构.

<型名...O>
类 对象创建者{
//...<型名 T>T 创建(){如 常式((是相同<T,O>::||...)){中 取<常 T&>(依赖_);}异 如 常式(是可默认构造值<T>){中 T{};}异 如 常式(是可构造<T,任何第一引用类型<对象创建者,T,远前无效,O...>>::){中 T{任何第一引用类型<对象创建者,T,远前无效,O...>{}};}异 如 常式(是可构造<T,任何第一类型<对象创建者,T,远前无效,O...>>::){中 T{任何第一类型<对象创建者,T,远前无效,O...>{}};}{中 创建多参对象<T>(造引序<10>{});}
}
//...
};

这里就是创建函数了:
1,首先判断是不是已绑定了要创建的类对象,如果绑定了,则直接从元组中取出返回.
2,未绑定的话,再判断是否可构造默认构造(即可无参构造),可以的话返回空对象.
3,然后判断是不是参数构造器,参数这里分成了两种,是引用类型或非引用类型.因为,识别TT&会引起冲突,所以分开处理.举例说明:

构 任何类型{<型名 T>符号 T(){中 T{};}<型名 T>符号 T&(){中 T{};}
};
类 例子{:例子(成员 m,){输出<<m.x<<行尾;}
};
例子 e(任何类型{},7);
//报错如下:
错误:转换 从'任何类型''成员'是 歧义
例子 e(任何类型{},7);
^~~~~~~~~
候选:'任何类型::符号 T()[带 T=成员]'
符号 T(){
^~~~~~~~
注意:候选:'任何类型::符号 T&()[带 T=成员]'
符号 T&(){

4,最后是构造多参构造器,分开一个参数和多个参数的原因是,一个参数需要处理拷贝构造器单参构造器冲突,按参数给创建多参对象函数传递了1~10整数序列,表示目前最多只能支持10个参数的构造器.

继续看多参的构造:

<型名 T,大小型...N>
T 创建多参对象(常 引序<N...>&){如 常式(是可构造值<T,<任何引用类型<对象创建者,远前无效,O...>,N>...>){中 T{<任何引用类型<对象创建者,远前无效,O...>,N>{}...};}{中 创建多参对象<T>(造引序<的大小...(N)-1>{});}
}

首先判断是否可由多个任何引用类型类型来构造,尽量,直接构造对象,否则,就减少参数个数来重新匹配.

任何类型

然后再观察如何编写任何类型,先看任何第一类型的情况.为了避免和拷贝构造器冲突,简单优化下:

构 任何第一类型{<型名 T,型名=允许如型<!是相同值<,T>>>常式 符号 T(){中 创建者_->元 创建<T>();}};

使用替失非错来先排除构造拷贝器,用任何第一类型识别参数类型时,需要按模版参数传递要构造的类给,让T不一样,进而告诉编译器要调用的不是拷贝构造器而是其他函数.

创建者_就是对象创建者对象,构造参数递归调用创建函数.多参也是类似,只是不需要额外判断拷贝构造器.

还要注意,如果构造器类型是引用类型,在和绑定参数匹配时,会多一次拷贝,所以还要区分.

<型名 创建者,型名 源,型名...O>
构 任何第一引用类型{<型名 T,型名=允许如型<!是相同值<,退化型<T>>>,型名=允许如型<(是相同<退化型<T>,O>::||...)>>常式 符号 T&(){中 常转<T&>(创建者_->元 取依赖<T>());}<型名 T,型名=允许如型<!是相同值<,退化型<T>>>,型名=允许如型<(是相同<退化型<T>,O>::||...)>>常式 符号 T&&(){中 静转<T&&>(常转<T&>(创建者_->元 取依赖<T>()));}创建者*创建者_=空针;
};

在和绑定参数匹配,且传递引用时,单独实现,直接返回,而不再调用创建者创建函数,并且强制转化.多参类型识别也是类似.

源码在此

相关文章:

2310C++构造对象

原文 本文展示一个构造对象方式,用户无需显式调用构造器.对有参构造器类,该实现在构造改对象时传递默认值来构造. 当然用户也可指定(绑定)某个参数的值.实现思路参考boost-ext/di的实现.看下示例: 构 成员{整 x10; }; 构 成员1{整 x11; }; 类 例子1{ 公:例子1(成员 x,成员1 x…...

nginx多文件组织

背景&#xff1a; nginx的话&#xff0c;有时候&#xff0c;想部署多个配置&#xff0c;比如&#xff1a;使用不同的端口配置不同的web工程。 比如&#xff1a;8081部署&#xff1a;项目1的web页面。 8082部署&#xff1a;项目2的web页面。 1)nginx.conf worker_processes…...

扩容LVM卷导致lvm元数据丢失的恢复过程

一、问题描述 因某次MySQL binlog占用过高扩容时&#xff0c;是直接对云盘操作&#xff0c;而扩容直接操作了lvm卷而未操作云盘分区&#xff0c;并随后执行了扩容的partprobe&#xff0c;resize2fs卷等操作&#xff1b;最后&#xff0c;显示并未扩容成功&#xff0c;重启系统后…...

【MySQL教程】| (1-1) 2023MySQL-8.1.0 安装教程

文章目录 一、安装包下载二、安装配置1、解压安装包2、编写MySQL配置文件3、初始化MySQL数据库3、安装mysql服务并启动4、MySQL服务5、连接MySQL6、修改密码 三、配置环境变量四、防止mysql自启动拖慢开机时间 近日有粉丝问到mysql在win11的安装中遇到一些问题&#xff0c;应粉…...

数据大屏定时请求后端数据

需求&#xff1a; 因为大屏基本从上午展示到晚上&#xff0c;不会频繁去打开页面。 前端实现&#xff1a; 在Vue的created钩子函数中发送初次请求&#xff0c;并使用JavaScript中的setInterval函数来设置整点定时发送请求。以下是一个示例 <template><div><h1…...

数据结构--队列

一、队列是什么 队列是一种特殊的线性表&#xff0c;特殊之处在于它只允许在表的前端&#xff08;front&#xff09;进行删除操作&#xff0c;而在表的后端&#xff08;rear&#xff09;进行插入操作&#xff0c;队列是一种操作受限制的线性表。进行插入操作的端称为队尾&…...

Python绘图系统25:新增8种绘图函数

文章目录 常用绘图函数单选框的更改逻辑源代码 Python绘图系统&#xff1a; 前置源码&#xff1a; Python打造动态绘图系统&#x1f4c8;一 三维绘图系统 &#x1f4c8;二 多图绘制系统&#x1f4c8;三 坐 标 轴 定 制&#x1f4c8;四 定制绘图风格 &#x1f4c8;五 数据生成导…...

(二) gitblit用户使用教程

(一)gitblit安装教程 (二) gitblit用户使用教程 (三) gitblit管理员手册 目录 网页访问git客户端设置推送错误配置查看当前配置 日常使用仓库分组my profile修改上传代码简洁 网页访问 点击Advanced... 点击Accept the Risk and Contiue 初始用户名和密码都是admin,点击login…...

8.3Jmeter使用json提取器提取数组值并循环(循环控制器)遍历使用

Jmeter使用json提取器提取数组值并循环遍历使用 响应返回值例如&#xff1a; {"code":0,"data":{"totalCount":11,"pageSize":100,"totalPage":1,"currPage":1,"list":[{"structuredId":&q…...

SNERT预备队招新CTF体验赛-Misc(SWCTF)

目录 1、最简单的隐写 2、旋转我 3、is_here 4、zip伪加密 5、压缩包密码爆破 6、我就藏在照片里 7、所以我放弃了bk 8、套娃 9、来自银河的信号 10、Track_Me 11、勇师傅的奇思妙想 1、最简单的隐写 下载附件后&#xff0c;图片格式并不支持打开 根据题目提示&…...

MySql017——组合查询

一、UNION作用 可用UNION操作符来组合数条SQL查询。 二、UNION 使用规则 1、UNION的使用很简单。所需做的只是给出每条SELECT语句&#xff0c;在各条语句之间放上关键字UNION。2、UNION必须由两条或两条以上的SELECT语句组成&#xff0c;语句之间用关键字UNION分隔&#xff…...

【0224】源码分析RelFileNode对smgr访问磁盘表文件的重要性(2)

1. RelFileNode的角色 RelFileNode 是一个结构体数据类型,声明于relfilenode.h(src\include\storage )头文件中,该数据类型十分重要,因为它 “提供所有我们需要知道的物理访问关系表的信息。” smgr要访问磁盘上面的数据表文件,则需要此RelFileNode提供必要信息。 可以说…...

2310C++λ中完美转发

原文 C11里面就引入了完美转发概念,通过它,可按参数实际类型转发参数. 元<型名 T>空 处理(T&t){输出<<"左值\n";} 元<型名 T>空 处理(T&&t){输出<<"右值\n";} 元<型名 T>空 测试转发(T&&t){处理(前向&…...

【C++11】std::function 包装器(又叫适配器),std::bind 绑定

文章目录 std::function 包装器1. 使用方法2. 包装器的应用场景&#xff1a;题目 - - 逆波兰表达式求值3. 成员函数 和 static 静态成员函数 使用 包装器 std::bind 适配器绑定1. 使用方法2. 调整参数 顺序3. 指定参数 / 参数个数的调整 std::function 包装器 std::function 包…...

Linux系统编程系列之线程

一、什么是线程 线程&#xff08;Thread&#xff09;是计算机中的基本执行单元&#xff0c;是操作系统调度的最小单位。线程是进程内的一个独立执行流程&#xff0c;一个进程可以包含多个线程&#xff0c;这些线程共享进程的资源&#xff0c;但每个线程都有自己的独立栈空间以及…...

CV面试知识点总结

一.卷积操作和图像处理中的中值滤波操作有什么区别&#xff1f; 1.1卷积操作 卷积操作是一种线性操作&#xff0c;通常用于特征的提取&#xff0c;通过卷积核的加权求和来得到新的像素值。1.2中值滤波 原文&#xff1a; https://blog.csdn.net/weixin_51571728/article/detai…...

Centos一键安装、切换各版本JDK

查看服务中的安装的jdk rpm -qa | grep java获取jdk各版本信息 yum -y list java*查看指定版本 yum -y list java*|grep 1.8安装jdk yum install java-11-openjdk当服务器中有多个版本jdk&#xff0c;切换指定jdk版本 alternatives --config java按照提示输入编号即可切换&…...

JavaWeb项目:smbms(mysql)

1.准备工作&#xff0c;创建数据库 CREATE DATABASE smbms;USE smbms;CREATE TABLE smbms_address (id BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID,contact VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 联系人姓名,addressDesc VARCHAR(50) COLLATE u…...

shell脚本的多线程介绍

shell脚本的多线程介绍 shell脚本中&#xff0c;实现多线程可以使用以下方法&#xff1a; 1&#xff09;使用&符号 在Shell中&#xff0c;可以使用&符号将命令放在后台执行&#xff0c;这样就可以同时执行多个命令。例如&#xff1a; #!/bin/bash command1 & #…...

周记之反思

9.25 这篇总结我承认&#xff0c;是在26号上午写的&#xff0c;那昨天晚上又聊天了&#xff0c;但是对比之前来说好很多了&#xff0c;所以26号上午也就是今天我起了个大早&#xff0c;然后把昨天的尾巴收了一下&#xff0c;没收完&#xff0c;先说说成果&#xff1a; 完成了…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...