C++系列-匿名对象
匿名对象
- 💢什么是匿名对象
- 💢匿名对象的创建方式及作用域
- 💢匿名对象的对象类型
- 💢💢匿名的基本数据类型对象
- 💢💢匿名的自定义的类类型对象
- 💢💢匿名的标准库的类对象
- 💢匿名对象的使用方式
- 💢💢作为临时值使用
- 💢💢可以调用成员
- 💢💢赋值和初始化
- 💢匿名对象的注意事项
- 💢💢权限问题
- 💢💢不能取地址
- 💢💢缺陷
💢什么是匿名对象
- 🥝匿名对象(Anonymous Object) 是指在创建对象的时候,并没有给它命名。
- 🥝它们通常用于在单个语句中执行一系列操作或调用某个函数,并且不需要将其结果存储到对象中。
💢匿名对象的创建方式及作用域
- 🍍直接在类名后加(),当遇到有参或者拷贝构造时,需要加上相应的参数。
- 🍍有名对象,其生命周期在当前函数局部域。
- 🍍匿名对象,其生命周期在当前行。
code:
#include <iostream>
using namespace std;class Person
{
public:Person(){cout << "Person默认构造" << endl;}Person(string name){cout << "Person有参构造" << endl;m_name = name;}Person(const Person& per){cout << "Person拷贝构造" << endl;}~Person(){cout << "析构析构析构" << endl;}void print_info(){cout << "name: " << m_name << endl;}private:string m_name="huahua";
};int main()
{Person per1; // 有名对象 -- 生命周期在当前函数局部域per1.print_info();Person().print_info(); // Person(),匿名对象 -- 生命周期在当前行Person("lili").print_info(); // Person("lili"),匿名对象 -- 生命周期在当前行Person(per1).print_info(); // Person(per1),匿名对象 -- 生命周期在当前行system("pause");return 0;
}result:
Person默认构造
name: huahua
Person默认构造
name: huahua
析构析构析构
Person有参构造
name: lili
析构析构析构
Person拷贝构造
name: huahua
析构析构析构
👉👉👉
这段代码中,Person().print_info(),Person(“lili”).print_info(),Person(per1).print_info()均是匿名对象。
他们只是实例化对象时,运行的构造函数不一样。 可以看到,当实例化匿名对象的那一行代码执行完之后,就执行了析构函数,释放对象。
而有名对象是在main函数的作用域,等main函数执行完后,才会执行析构函数(本案例中看不到,
因为最后可看到的的执行结果停留在system(“pause”))这一步。
💢匿名对象的对象类型
- 🍇匿名对象的类型可以是基本数据类型,如int,double, char等。
- 🍇匿名对象的类型可以是自定义的类类型。
- 🍇匿名对象的类型可以是标准库中的类类型。
💢💢匿名的基本数据类型对象
👉👉👉
int(5), double(3.14) char(‘A’)就是在创建匿名对象。
下面代码中的int(),int(3)是在创建匿名的int类型对象。 int a =
int(10)创建匿名对象int(10),并将其赋值给a,a就是有名对象。
code:
#include <iostream>
using namespace std;void test01()
{cout << "int(): " << int() << endl; // 创建匿名的int类型对象cout << "int(3): " << int(3) << endl;int a = int(10); // 创建匿名int类型对象int(10),赋值给有名的int对象acout << "int a = int(10): " << a << endl;
}
int main()
{test01();system("pause");return 0;
}result:
int(): 0
int(3): 3
int a = int(10): 10
💢💢匿名的自定义的类类型对象
👉👉👉
之前代码示例中的如下语句均为创建匿名对象。 Person().print_info(); // Person(),匿名对象
– 生命周期在当前行 Person(“lili”).print_info(); // Person(“lili”),匿名对象 – 生命周期在当前行 Person(per1).print_info(); // Person(per1),匿名对象 – 生命周期在当前行
而如下代码是在创建有名对象per1。 Person per1; // 有名对象 – 生命周期在当前函数局部域
💢💢匿名的标准库的类对象
#include <iostream>
#include <vector>
using namespace std;void print_vector(const vector<int>& vec)
{for (vector<int>::const_iterator it = vec.begin(); it < vec.end(); it++){cout << *it << " ";}cout << endl;
}void test01()
{print_vector(vector<int>{0, -1, -2}); // 创建匿名对象 vector<int>{0, -1, -2}vector<int> vect1{1, 2, 3}; // 创建有名对象vect1print_vector(vect1);vector<int> vect2 = vector<int>{ 4, 5, 6 }; // 创建匿名对象vect2print_vector(vect2);
}
int main()
{test01();system("pause");return 0;
}result:
0 -1 -2
1 2 3
4 5 6
💢匿名对象的使用方式
💢💢作为临时值使用
#include <iostream>
using namespace std;void print_info(int a)
{cout << a << endl;
}int main()
{print_info(3); // 这里的3可以看作是匿名的int对象,即int(3)system("pause");return 0;
}result:
3
💢💢可以调用成员
👉👉👉
之前代码示例中的如下语句中的匿名对象可以调用成员,但也只能调用一次,后面不会再用到它, 所以不需要有有名对象存储。
Person().print_info(); // Person(),匿名对象 – 生命周期在当前行
Person(“lili”).print_info(); // Person(“lili”),匿名对象 – 生命周期在当前行
Person(per1).print_info(); // Person(per1),匿名对象 – 生命周期在当前行
💢💢赋值和初始化
👉👉👉
下面代码中int a = Person(“Feifei”, 10).get_age(); 中,Person(“Feifei”,
10)是匿名对象,它调用了成员函数get_age(), 给变量a赋值。Person per1 = Person(“Maomao”, 13); 中,Person(“Maomao”,
13)匿名对象配置给有名对象per1。
#include <iostream>
using namespace std;class Person
{
public:Person(string name, int age) : m_name(name), m_age(age) {}int get_age(){return m_age;}
private:string m_name = "huahua";int m_age = 10;
};int main()
{// Person("Feifei", 10)匿名对象调用其成员函数给其它变量赋值int a = Person("Feifei", 10).get_age(); cout << "a:" << a << endl;// 匿名对象Person("Maomao", 13),可以用于初始化per1对象,Person per1 = Person("Maomao", 13); system("pause");return 0;
}result:
a:10
💢匿名对象的注意事项
💢💢权限问题
👉👉👉
下面代码中int a = Person(“Feifei”, 10).get_age();
中,Person(“Feifei”, 10)是匿名对象,它调用了成员函数get_age(), 给变量a赋值。Person per1 = Person(“Maomao”, 13); 中,Person(“Maomao”,
13)匿名对象配置给有名对象per1。
#include <iostream>
using namespace std;class Person
{
public:Person(string name, int age) : m_name(name), m_age(age) {}Person(Person& per) : m_name(per.m_name), m_age(per.m_age) {}int get_age(){return m_age;}void set_age(int age){m_age = age;}void print_info(){cout << "name: " << m_name << ", age: " << m_age << endl;}
private:string m_name = "huahua";int m_age = 10;
};int main()
{Person per1("Tiantian", 12); // 创建有名对象per1Person per2(per1); // 拷贝构造创建有名对象per2per2.print_info();system("pause");return 0;
}result:
name: Tiantian, age: 12
👉👉👉
以上代码中,先创建有名对象per1,然后利用per1创建有名对象per2。代码没有问题。 下面使用匿名函数实现。
#include <iostream>
using namespace std;class Person
{
public:Person(string name, int age) : m_name(name), m_age(age) {}Person(Person& per) : m_name(per.m_name), m_age(per.m_age) {}int get_age(){return m_age;}void set_age(int age){m_age = age;}void print_info(){cout << "name: " << m_name << ", age: " << m_age << endl;}
private:string m_name = "huahua";int m_age = 10;
};int main()
{// 想使用Person("Tiantian", 12)匿名对象去利用拷贝构造创建per2对象// 编译会报错,错误 C2558 class“Person” : 没有可用的复制构造函数或复制构造函数声明为“explicit”// 原因就在于这个匿名对象,它和临时对象一样是具有常性的,而在拷贝构造中,接收的是Person& per,// 用一个非常性的对象去引用常性的就会有问题。编译器会认为是权限放大的问题。Person per2(Person("Tiantian", 12)); per2.print_info();system("pause");return 0;
}
👉👉👉
以上代码中,想使用Person(“Tiantian”, 12)匿名对象去利用拷贝构造创建per2对象。
匿名对象,它和临时对象一样是具有常性的,而在拷贝构造中,接收的是Person& per,
用一个非常性的对象去引用常性的就会有问题。编译器会认为是权限放大的问题。会报错。 修改方法为:Person(Person& per) :
m_name(per.m_name), m_age(per.m_age) {} 在 Person& per前加上const修饰即可。加上const后实现了权限平移,此时既可以接受普通引用也可以接收常引用,提高了代码的健壮性。
💢💢不能取地址
cout << &Person("Tiantian", 12) << endl; 会报错。
因为匿名对象随时可能被销毁,如果取了其地址,后续的代码会变得不稳定,而且编译器可能会对匿名对象进行优化,
如果将其存储于寄存器中,就娶不到确定的内存地址。
💢💢缺陷
调试和维护上的困难,无法使用debug模式直接跟踪和check其当前值,增加调试难度。
如果频繁的创建和销毁匿名对象,会影响性能的开销。
相关文章:
C++系列-匿名对象
匿名对象 💢什么是匿名对象💢匿名对象的创建方式及作用域💢匿名对象的对象类型💢💢匿名的基本数据类型对象💢💢匿名的自定义的类类型对象💢💢匿名的标准库的类对象 &…...

tofixed和math.round什么区别
1、floor 返回不大于的最大整数(向下取整) 2、round 则是4舍5入的计算,入的时候是到大于它的整数(当-1.5时可见,四舍五入后得到的结果不是我们期待的,解决办法是先对他取绝对值,然后在用round方…...
OPENAIGC开发者大赛高校组金奖 | 基于混合大语言模型与多模态的全过程通用AI Agent
在第二届拯救者杯OPENAIGC开发者大赛中,涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到,我们特意开设了优秀作品报道专栏,旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者,希望能带给您…...
MySql批量迁移数据库
导出数据库 将指定数据库实例(MYSQL_HOST、MYSQL_PORT、MYSQL_USER、MYSQL_PASSWORD)中的所有数据库(表结构、数据)导出到指定目录(BACKUP_DIR)下的多个单独的SQL脚本,每个SQL脚本名称即为数据…...

一、selenium自动化简介selenium工具集
文章目录 一、简介二、组成部分三、selenium工具集3.1 Selenium IDE3.2 Selenium WebDriver3.3 Selenium Grid3.4 Appium 一、简介 官方网站 Selenium 是支持 web 浏览器自动化的一系列工具和库的综合项目。 它提供了扩展来模拟用户与浏览器的交互,用于扩展浏览器分…...

CCF推荐B类会议和期刊总结:(计算机网络领域)
CCF推荐B类会议和期刊总结(计算机网络领域) 在计算机网络领域,中国计算机学会(CCF)推荐的B类会议和期刊代表了该领域的较高水平。以下是对所有B类会议和期刊的总结,包括全称、出版社、dblp文献网址以及所属…...

[Web安全 网络安全]-文件包含漏洞
文章目录: 一:前言 1.什么是文件包含漏洞 2.文件包含漏洞的成因 3.文件包含漏洞的分类 4.文件包含漏洞的防御策略 5.文件包含函数(触发点Sink) 6.环境 6.1 靶场 6.2 其他工具 二:文件包含LFI labs靶场实验…...

使用soui4实现一个拾色器
拾色器类 #pragma once class CClrPickerCtrl : public SWindow {DEF_SOBJECT(SWindow, L"clrpicker") public:CClrPickerCtrl(void);~CClrPickerCtrl(void);//跟solider控件设置色调void SetSliderPos(int nPos);//获取选取位置的颜色COLORREF GetColor(); protect…...
Thinkphp5 + Swoole实现邮箱异步通知
在 ThinkPHP 中实现邮箱异步通知的常见做法是通过队列系统来处理异步任务,结合 Swoole 来处理异步发送邮件的请求。这样可以避免同步处理邮件发送导致的阻塞,提高响应速度。 以下是基于 ThinkPHP5 框架和 Swoole 的异步邮件通知实现步骤: 一…...

LLM - 理解 多模态大语言模型 (MLLM) 的预训练与相关技术 (三)
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/142063880 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 完备(F…...
工具篇之Joda-Time
在Java应用程序开发中,处理日期和时间是一项常见且复杂的任务。尽管Java标准库提供了基本的日期和时间操作类,但它们的使用常常不够直观和灵活。Joda-Time 是一个强大的日期和时间库,提供了丰富的API,用于简化日期和时间的操作。本…...
架构师应该懂得东西,软考应该具备的
架构师应该懂得知识 架构师作为软件系统设计和开发的关键角色,需要掌握广泛的知识和技能。具体来说,他们应该懂得以下几方面的知识: 编程语言:掌握至少一种编程语言,如Java、C、Python等,以便于进行系统设…...
图论篇--代码随想录算法训练营第五十一天打卡| 99. 岛屿数量(深搜版),99. 岛屿数量(广搜版),100. 岛屿的最大面积
99. 岛屿数量(深搜版) 题目链接:99. 岛屿数量 题目描述: 给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而…...

什么是API网关(API Gateway)?
1. 什么是API网关(API Gateway)? 在微服务体系结构中,客户端可能与多个前端服务进行交互。 API 网关位于客户端与服务之间。 它充当反向代理,将来自客户端的请求路由到服务。 它还可以执行各种横切任务,例…...

对话:LLC磁集成能否成为充电桩模块电源常态产品?
编者按:在终端需求疲软的影响下,前两年火热的新能源汽车、光伏、储能等新能源领域也掀起了价格战,储能已正式进入0.5元时代,新能源汽车领域价格战更是一轮接一轮,成本管控成为2024年企业绕不开的话题。 接下来我们将围…...

基于SSM的二手物品交易管理系统的设计与实现 (含源码+sql+视频导入教程+文档+PPT)
👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的二手物品交易管理系统7拥有两种角色 管理员:用户管理、分类管理、商品管理、订单管理、系统管理等 用户:登录注册、充值、收货、评价、收藏、购物车、订…...

视觉语言模型中的人脸社会感知
本文研究了视觉语言模型CLIP在处理人脸图像时的社会感知能力及其潜在偏见。研究者们构建了一个名为CausalFace的合成人脸数据集,通过系统地独立变化年龄、性别、人种、面部表情、照明和姿势等六个维度来评估模型的社会感知。他们发现,尽管CLIP是在多样化…...
JAVA学习-练习试用Java实现“最小覆盖子串”
问题: 给定一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。 注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。 示例 1&…...

关于axios同步获取数据的问题
axios同步获取数据 Axios介绍问题代码修改 总结 Axios介绍 Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 X…...
java-在ANTLR中,如何从java文件中提取类名和方法名0.1.8
java-在ANTLR中,如何从java文件中提取类名和方法名0.1.0 目标java源文件java的g4文件生成antlr代码最终代码调测结果阶段性总结 2024年9月12日11:16:01----0.1.8 目标 从一个java文件中提取出类名和方法名 java源文件 文件名是main.java,具体内容如下…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...

spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
前端工具库lodash与lodash-es区别详解
lodash 和 lodash-es 是同一工具库的两个不同版本,核心功能完全一致,主要区别在于模块化格式和优化方式,适合不同的开发环境。以下是详细对比: 1. 模块化格式 lodash 使用 CommonJS 模块格式(require/module.exports&a…...