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

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++系列-匿名对象

匿名对象 &#x1f4a2;什么是匿名对象&#x1f4a2;匿名对象的创建方式及作用域&#x1f4a2;匿名对象的对象类型&#x1f4a2;&#x1f4a2;匿名的基本数据类型对象&#x1f4a2;&#x1f4a2;匿名的自定义的类类型对象&#x1f4a2;&#x1f4a2;匿名的标准库的类对象 &…...

tofixed和math.round什么区别

1、floor 返回不大于的最大整数&#xff08;向下取整&#xff09; 2、round 则是4舍5入的计算&#xff0c;入的时候是到大于它的整数&#xff08;当-1.5时可见&#xff0c;四舍五入后得到的结果不是我们期待的&#xff0c;解决办法是先对他取绝对值&#xff0c;然后在用round方…...

OPENAIGC开发者大赛高校组金奖 | 基于混合大语言模型与多模态的全过程通用AI Agent

在第二届拯救者杯OPENAIGC开发者大赛中&#xff0c;涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到&#xff0c;我们特意开设了优秀作品报道专栏&#xff0c;旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者&#xff0c;希望能带给您…...

MySql批量迁移数据库

导出数据库 将指定数据库实例&#xff08;MYSQL_HOST、MYSQL_PORT、MYSQL_USER、MYSQL_PASSWORD&#xff09;中的所有数据库&#xff08;表结构、数据&#xff09;导出到指定目录&#xff08;BACKUP_DIR&#xff09;下的多个单独的SQL脚本&#xff0c;每个SQL脚本名称即为数据…...

一、selenium自动化简介selenium工具集

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

CCF推荐B类会议和期刊总结:(计算机网络领域)

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

[Web安全 网络安全]-文件包含漏洞

文章目录&#xff1a; 一&#xff1a;前言 1.什么是文件包含漏洞 2.文件包含漏洞的成因 3.文件包含漏洞的分类 4.文件包含漏洞的防御策略 5.文件包含函数&#xff08;触发点Sink&#xff09; 6.环境 6.1 靶场 6.2 其他工具 二&#xff1a;文件包含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 中实现邮箱异步通知的常见做法是通过队列系统来处理异步任务&#xff0c;结合 Swoole 来处理异步发送邮件的请求。这样可以避免同步处理邮件发送导致的阻塞&#xff0c;提高响应速度。 以下是基于 ThinkPHP5 框架和 Swoole 的异步邮件通知实现步骤&#xff1a; 一…...

LLM - 理解 多模态大语言模型 (MLLM) 的预训练与相关技术 (三)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142063880 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 完备(F…...

工具篇之Joda-Time

在Java应用程序开发中&#xff0c;处理日期和时间是一项常见且复杂的任务。尽管Java标准库提供了基本的日期和时间操作类&#xff0c;但它们的使用常常不够直观和灵活。Joda-Time 是一个强大的日期和时间库&#xff0c;提供了丰富的API&#xff0c;用于简化日期和时间的操作。本…...

架构师应该懂得东西,软考应该具备的

架构师应该懂得知识 架构师作为软件系统设计和开发的关键角色&#xff0c;需要掌握广泛的知识和技能。具体来说&#xff0c;他们应该懂得以下几方面的知识&#xff1a; 编程语言&#xff1a;掌握至少一种编程语言&#xff0c;如Java、C、Python等&#xff0c;以便于进行系统设…...

图论篇--代码随想录算法训练营第五十一天打卡| 99. 岛屿数量(深搜版),99. 岛屿数量(广搜版),100. 岛屿的最大面积

99. 岛屿数量&#xff08;深搜版&#xff09; 题目链接&#xff1a;99. 岛屿数量 题目描述&#xff1a; 给定一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的矩阵&#xff0c;你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而…...

什么是API网关(API Gateway)?

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

对话:LLC磁集成能否成为充电桩模块电源常态产品?

编者按&#xff1a;在终端需求疲软的影响下&#xff0c;前两年火热的新能源汽车、光伏、储能等新能源领域也掀起了价格战&#xff0c;储能已正式进入0.5元时代&#xff0c;新能源汽车领域价格战更是一轮接一轮&#xff0c;成本管控成为2024年企业绕不开的话题。 接下来我们将围…...

基于SSM的二手物品交易管理系统的设计与实现 (含源码+sql+视频导入教程+文档+PPT)

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

视觉语言模型中的人脸社会感知

本文研究了视觉语言模型CLIP在处理人脸图像时的社会感知能力及其潜在偏见。研究者们构建了一个名为CausalFace的合成人脸数据集&#xff0c;通过系统地独立变化年龄、性别、人种、面部表情、照明和姿势等六个维度来评估模型的社会感知。他们发现&#xff0c;尽管CLIP是在多样化…...

JAVA学习-练习试用Java实现“最小覆盖子串”

问题&#xff1a; 给定一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 。 注意&#xff1a;如果 s 中存在这样的子串&#xff0c;我们保证它是唯一的答案。 示例 1&…...

关于axios同步获取数据的问题

axios同步获取数据 Axios介绍问题代码修改 总结 Axios介绍 Axios 是一个基于 promise 网络请求库&#xff0c;作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 X…...

java-在ANTLR中,如何从java文件中提取类名和方法名0.1.8

java-在ANTLR中&#xff0c;如何从java文件中提取类名和方法名0.1.0 目标java源文件java的g4文件生成antlr代码最终代码调测结果阶段性总结 2024年9月12日11:16:01----0.1.8 目标 从一个java文件中提取出类名和方法名 java源文件 文件名是main.java&#xff0c;具体内容如下…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 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关&#xff0…...

html-<abbr> 缩写或首字母缩略词

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

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...