二、类与对象(四)

22 内部类

22.1 内部类的概念

如果一个类定义在另一个类的内部,这个类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员,外部类对内部类没有任何优越的访问权限,也就是说它和定义在一个全局的类没有什么区别,只是受外部类的类域限制。

例:

#include <iostream>
using namespace std;
class A
{
private:
    int h;
public:
    class B
    {
    private:
        int b;
    };
};
int main()
{
    //B bb; //错误代码
    A::B bb;//B受A的类域限制
    return 0;
}

22.2 内部类的特性

  1. 内部类天生就是外部类的友元,即内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。

例:

#include <iostream>
using namespace std;
class A
{
private:
    static int k;
    int h;
public:
    class B // B天生就是A的友元
    {
    public:
        void foo(const A& a)
        {
            //B可以访问A的私有成员
            cout << k << endl;//OK
            cout << a.h << endl;//OK
        }
    };
};
int A::k = 1;
int main()
{
    A::B b;
    b.foo(A());
    return 0;
}

运行结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 内部类可以定义在外部类的publicprotected、和private也就是任何位置。

  2. sizeof(外部类)= 外部类,和内部类没有任何关系。

例:

#include <iostream>
using namespace std;
class A
{
private:
    int h;
public:
    class B
    {
    private:
        int b;
    };
};
int main()
{
    A aa;
    cout << sizeof(aa) << endl;
    return 0;
}

运行结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

23 匿名对象

23.1 匿名对象的引入及特性

以往我们调用成员函数的时候,通常的做法是会先定义一个对象,然后再通过这个对象去调用函数,但是有些时候比如我们在做题目,某个函数只需要被调用一次就可以了,如果定义一个对象才能调用就有些麻烦了,这个时候我们就可以通过匿名对象来对函数进行调用。

以往我们说不能用A aa1();这样的方式来定义对象,因为编译器无法识别这是一个函数声明,还是对象定义。

定义匿名对象的方式和上面的方式类似,但是它不用取名字,而且匿名对象的生命周期只在它出现的那一行

例:

#include <iostream>
using namespace std;
class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
class Solution {
public:
	int Sum_Solution(int n) {
		//...
		return n;
	}
};
int main()
{
	A();
	cout << "-----" << endl;
	cout << Solution().Sum_Solution(10) << endl;
	return 0;
}

运行结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从输出结果可以看到,27行的时候定义了一个匿名对象,到了28行后它就自动调用了析构函数。

除此之外,29行还展示了匿名对象的应用场景,即对于那些需要通过对象来调用函数但对象本身并不重要的情况,就可以通过匿名对象进行调用。当然还有一些其他使用场景,这个等以后遇到再说。

23 编译器对拷贝对象时的一些优化

在传参和传返回值的过程中,为减少对象的拷贝,通常编译器会对以下场景做一些优化:

23.1 连续构造和拷贝构造时的优化

#include <iostream>
using namespace std;
class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	A(const A& aa)
		:_a(aa._a)
	{
		cout << "A(const A& aa)" << endl;
	}
	A& operator=(const A& aa)
	{
		cout << "A& operator=(const A& aa)" << endl;
		if (this != &aa)
		{
			_a = aa._a;
		}
		return *this;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};

int main()
{
	A aa1 = 1;//构造+拷贝构造
    
	return 0;
}

运行结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从输出结果可以看到,35行代码本来应该涉及一个构造和一个拷贝构造,但被编译器优化后只涉及一个构造。

23.2 参数类型为引用时的优化

#include <iostream>
using namespace std;
class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	A(const A& aa)
		:_a(aa._a)
	{
		cout << "A(const A& aa)" << endl;
	}
	A& operator=(const A& aa)
	{
		cout << "A& operator=(const A& aa)" << endl;
		if (this != &aa)
		{
			_a = aa._a;
		}
		return *this;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
void Fun2(const A& aa)
{

}
int main()
{
	A aa1 = 1;
	cout << "-----" << endl;
	Fun2(aa1);//aa只是aa1的别名,无优化
	cout << "-----" << endl;
	Fun2(2);//构造一个临时变量后给别名,无优化
	cout << "-----" << endl;
	Fun2(A(3));//

	return 0;
}

运行结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从输出结果可以看到, 当函数参数类型为引用时,因为形参只是实参的一个别名,所以不需要做任何优化。

结论:尽量使用const &传参。

23.3 传值返回时的优化

#include <iostream>
using namespace std;
class A
{
public:
	A(int a = 0)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	A(const A& aa)
		:_a(aa._a)
	{
		cout << "A(const A& aa)" << endl;
	}
	A& operator=(const A& aa)
	{
		cout << "A& operator=(const A& aa)" << endl;
		if (this != &aa)
		{
			_a = aa._a;
		}
		return *this;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
void Fun1(A aa)
{

}
void Fun2(const A& aa)
{

}
A Fun3()
{
	A aa;//构造
	return aa;//拷贝构造
}
A Fun4()
{
	return A();
}
int main()
{
	A aa1 = 1;
	cout << "-----" << endl;
	Fun3();//无优化
	cout << "-----" << endl;
	A aa2 = Fun3();//本来应该是一个构造,两个拷贝构造,但被编译器优化为一个构造和一个拷贝构造
	cout << "-----" << endl;
	Fun4();//构造+拷贝构造->优化为直接构造
	A aa3 = Fun4();//构造+拷贝构造+拷贝构造->优化为直接构造
	cout << "-----" << endl;
	return 0;
}

运行结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从输出结果可以看到,51行代码本来应该涉及一个构造和两个拷贝构造,但被编译器优化为和49行代码一样,只涉及一个构造和一个拷贝构造。除此之外,58行代码直接返回一个匿名对象时,本来应该涉及一个构造和两个拷贝构造,但被编译器优化后,只涉及一个构造。

需要注意的是,下面这种情况无法优化:

A aa1;
aa1 = Fun4();

原因在于,和A aa3 = Fun4();相比,aa1 = Fun4();还涉及到赋值运算符的重载,这将干扰优化的进行。

结论:

  1. 接收返回值对象,尽量以拷贝构造的方式接收,不要赋值接收。
  2. 函数中返回对象时,尽量返回匿名对象。

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

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

相关文章

HarmonyOS应用开发者基础认证/HarmonyOS应用开发者高级认证

基础和高级认证的区别都是差不多&#xff0c;都是随机赛选的题目。 本次题目不保证完全一样&#xff0c;可以做些拿来练习 目录 判断题 单选题 多选题 判断题 video 组 件 可 以 ⽀ 持 本 地 视 频 路 径 和 ⽹ 络 路 径 播 放 。 播 放 ⽹ 络 视 频 时 &#xff0c; 需 要…

RT_Thread 调试笔记:串口打印、MSH控制台 相关

说明&#xff1a;记录日常使用 RT_Thread 开发时做的笔记。 持续更新中&#xff0c;欢迎收藏。 1.打印相关 1.打印宏定义&#xff0c;可以打印打印所在文件&#xff0c;函数&#xff0c;行数。 #define PRINT_TRACE() printf("-------%s:%s:%d------\r\n", __FIL…

书生浦语大模型概述

github 地址&#xff1a;https://github.com/InternLM/tutorial 一、大模型简介 二、书生浦语 介绍 2.1 简介 2.2 模型到应用 如上图所示&#xff0c;从模型到应用通过共需要经过以下4个步骤&#xff1a; 模型评测&#xff1a;选择适合自己需求的模型。 不同的大模型&#x…

将yolov8的检测框从正框修改为旋转框需要做那些修改?

将yolov8项目修改为yolov8_obb项目需要修改模型结构(增加角度预测)、dataloader(使其支持dota格式数据)、修改TaskAlignedAssigner(使其支持带角度的bbox)、修改loss(新增对角度的训练)、修改metric(将hbb指标titile修改为obb)、修改绘图代码(使其能绘制旋转框)。 …

USB -- STM32F103缓冲区描述表及USB数据存放位置讲解(续)

目录 链接快速定位 前沿 1 0x40005C00和0x40006000地址的区别和联系 2 USB_BTABLE寄存器介绍 3 USB缓冲区描述表&#xff08;SRAM&#xff09;介绍 3.1 发送缓冲区地址寄存器n&#xff08;n[0..7]&#xff09; 3.2 发送数据字节数寄存器n&#xff08;n[0..7]&#xff09…

FindMy技术用于键盘

键盘是我们生活中不可或缺的输入工具&#xff0c;是人与计算机之间沟通的桥梁&#xff0c;无论是编写文档、浏览网页、玩游戏、或是进行复杂的数据分析&#xff0c;键盘都在其中发挥着关键的作用。此外&#xff0c;键盘还是各种软件的快捷键操作的关键。通过熟练地运用快捷键&a…

SpringBoot+Vue轻松实现考试管理系统

简介 本系统基于 Spring Boot 搭建的方便易用、高颜值的教学管理平台&#xff0c;提供多租户、权限管理、考试、练习、在线学习等功能。主要功能为在线考试、练习、刷题&#xff0c;在线学习。课程内容支持图文、视频&#xff0c;考试类型支持考试、练习、问卷。 源码下载 网…

程序性能优化全能手册

本文聊一个程序员都会关注的问题&#xff1a;性能。 当大家谈到“性能”时&#xff0c;你首先想到的会是什么&#xff1f; 是每次请求需要多长时间才能返回&#xff1f; 是每秒钟能够处理多少次请求&#xff1f; 还是程序的CPU和内存使用率高不高&#xff1f; 这些问题基本上…

专业实习day3、4(路由器做内网访问公网)

专业实习 代码 display ip interface brief 显示当前设备下所有接口IP undo IP地址支持覆盖&#xff0c;但是正常的命令不能覆盖必须undo&#xff08;删除&#xff09;掉 un in en 在做配置的过程中&#xff0c;设备系统一般都会出现一些提示或者告警之类的东西&#xff0c;从…

打造私域流量的知识付费小程序saas租户平台

当今信息爆炸的时代&#xff0c;知识管理已经成为了每个人必须面对的问题。然而&#xff0c;市面上的知识付费平台大多数都是通用的&#xff0c;无法满足个性化需求。 因此&#xff0c;明理信息科技提供了一款专属定制的适合个人的知识付费平台。核心产品能力如下&#xff1a;…

【kettle】pdi/data-integration 集成kerberos认证连接hdfs、hive或spark thriftserver

一、背景 kerberos认证是比较底层的认证&#xff0c;掌握好了用起来比较简单。 kettle完成kerberos认证后会存储认证信息在jvm中&#xff0c;之后直接连接hive就可以了无需提供额外的用户信息。 spark thriftserver本质就是通过hive jdbc协议连接并运行spark sql任务。 二、…

第12课 利用openCV检测物体是否运动了

FFmpeg与openCV绝对是绝配。前面我们已经基本熟悉了FFmpeg的工作流程&#xff0c;这一章我们重点来看看openCV。 在前面&#xff0c;我们已经使用openCV打开过摄像头并在MFC中显示图像&#xff0c;但openCV能做的要远超你的想像&#xff0c;比如可以用它来实现人脸检测、车牌识…

服务号怎么改为订阅号

服务号和订阅号有什么区别&#xff1f;服务号转为订阅号有哪些作用&#xff1f;很多小伙伴想把服务号改为订阅号&#xff0c;但是不知道改了之后具体有什么作用&#xff0c;今天跟大家具体讲解一下。首先我们知道服务号一个月只能发四次文章&#xff0c;但是订阅号每天都可以发…

GLTF编辑器设置3D纺织纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 位移贴图是一种纹理映射技术&#xff0c;通过改变顶点的位置来模拟细…

掌握人像抠图的艺术:从工具到技巧,完美处理每一细节

在图像的编辑长河中&#xff0c;抠图仿佛一把神奇的画笔&#xff0c;能从画布中提取出我们想要的每一笔&#xff0c;使之与其他画面完美交融。而人像抠图&#xff0c;作为其分支&#xff0c;对精细度的要求更为严格。这需要我们精心提取出人像&#xff0c;使之边缘清晰、无多余…

函数图像化

函数图像化 在进行模型提取时&#xff0c;往往会需要选择拟合的函数&#xff0c;因此&#xff0c;了解函数的图像对于模型拟合提取有益&#xff0c;以下是常见的一些函数的曲线 1 二次函数 常见的耳二次函数曲线&#xff0c;转换x与y数量级差异仅一个数量级&#xff0c; 2 三…

DragonEnglish:COCA20000+单词+释义

去年的时候接触到了 COCA20000 单词&#xff0c;对这种给单词特定顺序的方式蛮感兴趣的。因为我当时接触的版本只有单词或者单词释义的版本&#xff0c;所以我直接通过各种方式给它搭配了音标例句发音&#xff0c;然后每100个切割成1份&#xff0c;分成了 202 个文件来学习&…

C# visual studio COM创建及调用

1.visual studuio操作 1.1visual Studio创建类库项目ClassLibrary1。 1.1.1ClassLibrary1项目Class1.cs内容如下&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.T…

加密的手机号如何模糊查询?

1 一次加载到内存 实现这个功能&#xff0c;我们第一个想到的办法可能是&#xff1a;把个人隐私数据一次性加载到内存中缓存起来&#xff0c;然后在内存中先解密&#xff0c;然后在代码中实现模糊搜索的功能。 这样做的好处是&#xff1a;实现起来比较简单&#xff0c;成本非常…

实习记录留存

0.前提 实习结束了我留个档方便以后查看 校内实习玩具_哔哩哔哩_bilibili 不如这个爽 带兄弟们飙车_哔哩哔哩_bilibili