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

C++类与对象(下)--最后的收尾

在这里插入图片描述

内部类

如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类。内部类是⼀个独⽴的类,跟定义在 全局相⽐,他只是受外部类类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类。

#include<iostream>
using namespace std;
class A
{
private:
static int _k;
int _h = 1;
public:
class B // B默认就是A的友元
{
public:
void foo(const A& a)
{
cout << _k << endl; //OK
cout << a._h << endl; //OK
}
};
};
int A::_k = 1;
int main()
{
cout << sizeof(A) << endl;
A::B b;
A aa;
b.foo(aa);
return 0;
}

我们来计算一下对象A的大小:
在这里插入图片描述
static修饰的成员变量,也就是静态成员变量并没有存储在空间里面,所以只算了int _h = 1;的大小,但是B不算,因为内部类不是附属关系,只是说B的类域受到了A的限制

这里还要再说明的是,也会受到访问限定符的限制,如果把class B前面的public换成private也就会报错

内部类默认是外部类的友元类。

看上面的代码,也就是说B可以访问A的私有成员

内部类本质也是⼀种封装,当A类跟B类紧密关联,A类实现出来主要就是给B类使⽤,那么可以考 虑把A类设计为B的内部类,如果放到private/protected位置,那么A类就是B类的专属内部类,其 他地⽅都⽤不了。

总的来说,C++不喜欢用内部类,用的也不是很多,但是JAVA会用的比较多

再来回顾上次做过的一道OJ题

求1+2+3+…+n

描述

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

数据范围: 0<n≤2000<n≤200
进阶: 空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n)

示例1:

输入:
5返回值:
15

示例2

输入:
1返回值:
1

用内部类的情况下可以这样做:

class Solution {
// 内部类
class Sum
{
public:
Sum()
{
_ret += _i;
++_i;
}
};
static int _i;
static int _ret;
public:
int Sum_Solution(int n) {
// 变⻓数组
Sum arr[n];
return _ret;
}
};
int Solution::_i = 1;
int Solution::_ret = 0;

匿名对象

这是相当重要的知识,后续的学习还是非常常见的

⽤ 类型(实参) 定义出来的对象叫做匿名对象,相⽐之前我们定义的 类型 对象名(实参) 定义出来的 叫有名对象。

来看示例:

//有名对象,生命周期在main函数结束以后
A aa1(1);
A aa2;
//匿名对象
A(1);
A();//无参的时候必须要加括号,否则无法区分,而且匿名对象的生命周期只有一行

匿名对象⽣命周期只在当前⼀⾏,⼀般临时定义⼀个对象当前⽤⼀下即可,就可以定义匿名对象。

匿名对象的应用场景

1)调用构造函数的时候,减少代码的书写量:

Solution s1;
cout << s1.Sum_Solution(10) << endl;
//优化后的代码
cout << Solution().Sum_Solution(10) << endl;

2)匿名对象能否被引用?

答案是可以。匿名对象和临时对象一样也具有常性

正确的书写形式如下:

const A & r=A();

和临时对象不一样的是,匿名对象的生命周期被延长了。

试想一下:

如果用完了,就销毁,那么引用的意义何在?引用不就成了野引用,这里的匿名对象的生命周期取决于引用的生命周期,也就是main函数结束之后再析构

打个比方来说:

匿名对象特别像一次性筷子,但是要去露营了,三天的时间外面没有换筷子的地方,所以也就将就着用了,它的生命周期也取决于编译器

对象拷⻉时的编译器优化

现代编译器会为了尽可能提⾼程序的效率,在不影响正确性的情况下会尽可能减少⼀些传参和传返 回值的过程中可以省略的拷⻉。

代码如下:

A f2()
{
A aa;
return aa;
}
int main()
{A aa2=f2();cout<<endl;return 0;
}

逻辑图如下:
在这里插入图片描述
进程地址图如下:
在这里插入图片描述
这里编译器会觉得有些浪费,两次拷贝构造会浪费空间

在VS2019会有第一次优化:
在这里插入图片描述
直接让aa拷贝构造给aa2

如果关闭优化呢?

情况如下:
在这里插入图片描述
代码:

A f2()
{
A aa;
return aa;
}
int main()
{
// 传值传参
A aa1;
f1(aa1);
cout << endl;
// 隐式类型,连续构造+拷⻉构造->优化为直接构造
f1(1);
// ⼀个表达式中,连续构造+拷⻉构造->优化为⼀个构造
f1(A(2));
cout << endl;
// 传值返回
// 返回时⼀个表达式中,连续拷⻉构造+拷⻉构造->优化⼀个拷⻉构造 (vs2019 debug)
// ⼀些编译器会优化得更厉害,进⾏跨⾏合并优化,直接变为构造。(vs2022 debug)
f2();
cout << endl;
// 返回时⼀个表达式中,连续拷⻉构造+拷⻉构造->优化⼀个拷⻉构造 (vs2019 debug)
// ⼀些编译器会优化得更厉害,进⾏跨⾏合并优化,直接变为构造。(vs2022 debug)
A aa2 = f2();
cout << endl;
// ⼀个表达式中,连续拷⻉构造+赋值重载->⽆法优化
aa1 = f2();
cout << endl;
return 0;
}

22相比较19,传值返回有着很大的不同,22把拷贝构造都拿掉了,22没有创建aa,aa是aa2的别名,aa相当于一个指针,全程没有拷贝。
在这里插入图片描述在这里插入图片描述
22中也可以理解为把临时对象拷贝给了aa1,函数调用的时候

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • jmeter依赖jar包找不到类路径
  • SQL入门题
  • 【IPV6从入门到起飞】5-3 IPV6+Home Assistant(ESP32+MQTT+GPIO)远程控制灯
  • Java 抽象类 接口--详解
  • 判断语句有几种写法
  • 【解决】AnimationCurve 运行时丢失数据问题
  • 三十三、Gin的中间件
  • 使用 ECharts 实现响应式图表:优化移动端用户体验
  • QT如何通过QTableWidget控件开发表格功能
  • 默认端口被占用后,如何修改Apache2 端口
  • Vue3 : ref 与 reactive
  • 计算机组成原理——第二章(19)
  • 基于SpringBoot的考研资讯平台设计与实现
  • 关于Python爬虫的基础知识
  • 如何实现过滤器、拦截器和全局异常捕获?
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • python3.6+scrapy+mysql 爬虫实战
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • CSS盒模型深入
  • extjs4学习之配置
  • happypack两次报错的问题
  • Java,console输出实时的转向GUI textbox
  • MaxCompute访问TableStore(OTS) 数据
  • php中curl和soap方式请求服务超时问题
  • vue的全局变量和全局拦截请求器
  • 记一次用 NodeJs 实现模拟登录的思路
  • 前端性能优化——回流与重绘
  • 前端学习笔记之观察者模式
  • 试着探索高并发下的系统架构面貌
  • 源码安装memcached和php memcache扩展
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • ​探讨元宇宙和VR虚拟现实之间的区别​
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • (31)对象的克隆
  • (js)循环条件满足时终止循环
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)编辑寄语:因为爱心,所以美丽
  • (转)大型网站架构演变和知识体系
  • (转)真正的中国天气api接口xml,json(求加精) ...
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • . NET自动找可写目录
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .net framework profiles /.net framework 配置
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .NET 设计一套高性能的弱事件机制
  • [ 渗透测试面试篇 ] 渗透测试面试题大集合(详解)(十)RCE (远程代码/命令执行漏洞)相关面试题
  • [20180224]expdp query 写法问题.txt
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [Angular] 笔记 7:模块