波奇学C++:友元函数,友元类,内部类,匿名对象,优化构造

news2024/11/29 10:44:54

友元函数/类 :突破访问限定符,允许非同一个类的函数或者类访私有成员变量。

class A
{
public:
	A()
		:_a(0)
		,_b(1)
	{
		cout << "A()" << endl;
	}
private:
	int _a = 0;
	int _b = 1;
};
void fun(const A& a)
{
	cout << a._a << endl;
}

这个代码会报错,原因是_a是a._a的私有成员,fun()是类外函数不能访问。

加上友元就可以突破限制

class A
{
	friend void fun(const A& a);
public:
	A()
		:_a(0)
		,_b(1)
	{
		cout << "A()" << endl;
	}
private:
	int _a = 0;
	int _b = 1;
};
void fun(const A& a)
{
	cout << a._a << endl;
}

关于友元的知识

友元函数是一种声明,表明这个函数可以访问私有变量。

友元函数本质上不属于类函数,所以这个声明是不受访问限定符限制的,可以定义在public或者private中。

一个函数可以是多个类的友元函数。

友元函数会破快封装性,所以尽量不要用友元。

友元类:

class A
{
	friend class B;
public:
	A()
		:_a(0)
		,_b(1)
	{
		cout << "A()" << endl;
	}
private:
	int _a = 0;
	int _b = 1;
};
class B
{
public:
	void fun(const A& a)
	{
		cout << a._a << endl;
	}
private:
	int _c = 1;
	
};

将fun封装到class B中,在A中用友元声明,使得fun()函数可以访问A中的私有成员变量。

内部类是在类中再嵌套一个类。

class A
{
	
public:
	class B
	{
	public:
		void fun(const A& a)
		{
			cout << a._a << endl;
		}
	private:
		int _c = 1;

	};
	A()
		:_a(0)
		,_b(1)
	{
		cout << "A()" << endl;
	}
private:
	int _a = 0;
	int _b = 1;
};

如图在class A中定义一个类class B

计算类的大小

cout << sizeof(A) << endl;//结果为8

我们知道计算类的大小是不计算函数的,那么B类为什么不会计算到其中,因为B类在其中相当于声明。当然class A也是一种声明,本身应该不应该有大小,sizeof是计算创建A的实例的大小。sizeof(A)可以看成创建类A的实例后计算大小,如果创建A的实例是不会有类B成员的,只有_a,_b成员。把代码修改成

class A
{
	
public:
	class B
	{
	public:
		void fun(const A& a)
		{
			cout << a._a << endl;
		}
	private:
		int _c = 1;

	};
	A()
		:_a(0)
		,_b(1)
	{
		cout << "A()" << endl;
	}
private:
	int _a = 0;
	int _b = 1;
	B b;
};

结果是12,计算了B类成员的大小。

1.类声明本身是没有大小的,相当于图纸。

2.sizeof(类),计算的是类的实例的大小。如果类创建的成员变量有内部类实例,那么会计算内部类的大小,如果成员变量没有,只有类声明那就不算内部类大小。

3.类大小只算成员变量大小。

内部类的性质

内部类是类的友元类,可以在内部类访问类的私有变量,但是类不是内部类的友元类,所以不能访问内部类的私有成员变量。

B可以访问_a,_b,A不能访问_c

匿名对象

class A
{
public:
	A()
		:_a(0)
		, _b(1)
	{
		cout << "A()" << endl;
	}
	void fun()
	{
		cout << "fun()" << endl;
	}
private:
	int _a = 0;
	int _b = 1;
};
A a;//有名对象
A();//匿名对象

有名对象无匿名对象的区别:

有名对象--生命周期在当前函数局部域。

匿名对象--生命周期在当前行。/这行代码运行结束后就会调用析构函数。*‘

有名对象不能加括号:不知道是对象还是函数名

A a();/无法分辨是对象还是函数,传参初始化是可以加。

匿名对象和临时对象具有常性。

const A&aa=A();

匿名对象如果被引用不会变成野引用 const引用延长了匿名对象的生命周期,生命周期在当前函数局部域,就是函数结束时才调用析构函数。

匿名函数的使用场景:更简单地调用类成员函数

//第一种方式
A a;
a.fun();
//第二种方式
A().fun();

传参时省略创建实例

编译器会对同一条表达式调用多个构造函数时进行优化

如拷贝构造+构造函数可能直接被优化为构造函数。

A a=2;

这发生类型转换,先生成临时变量const A b(2),临时变量再对A拷贝构造A a(const A b),编译会直接优化成A a(2)不调用临时拷贝,但用const A& c=2,可以证明临时变量确实会生成。

接收传值时优化

返回A时有拷贝构造,生成临时对象,生成的临时对象初始化ra也调用拷贝构造。(不是等号运算符重载,因为A ra是被初始化的)

 编译器会优化成两次拷贝构造会被合成一次拷贝构造。

//避免的写法
A ra;
A ra=fun5();
//这就不是两次构造了

 传参时优化

void fun6(A a)
{
}
//不是同一行表达式,不会优化,构造+拷贝构造
A a(1);
fun6(a);
//匿名,会优化
fun6(A(1));
//最佳写法,隐式类型转换,会优化
fun6(1);

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

canal学习-运行canal-adapter源码并记录解决报错问题(一)

运行canal-adapter 1. 下载canal源码1.1 下载源码并安装好环境1.2 查看目录结构 2.项目运行2.1 项目打包2.2 项目打包可能遇到的问题&#xff1a;1.Failure to find com.alibaba.otter:connector.tcp:jar:jar-with-dependencies:1.1.52.com.alibaba.druid.pool.DruidDataSource…

HTTP协议与TCP协议

HTTP协议 1. HTTP有哪些⽅法&#xff1f; HTTP 1.0 标准中&#xff0c;定义了3种请求⽅法&#xff1a;GET、POST、HEAD HTTP 1.1 标准中&#xff0c;新增了请求⽅法&#xff1a;PUT、PATCH、DELETE、OPTIONS、TRACE、CONNECT 2. 各个HTTP方法的具体作用是什么&#xff1f; 方…

量子计算:揭开未来计算世界的面纱

随着科技的飞速发展&#xff0c;计算能力的提升成为人们关注的焦点之一。而在这个领域中&#xff0c;量子计算正逐渐成为备受瞩目的新星。量子计算利用了量子力学的原理&#xff0c;与传统计算方式有着根本的不同。在传统计算中&#xff0c;信息以比特的形式表示&#xff0c;而…

COMSOL光电专题第三十三期(线上),COMSOL声学(北京线下)专题线上通知

背景&#xff1a; COMSOL多物理场仿真软件以高效的计算性能和杰出的多场耦合分析能力实现了精确的数值仿真&#xff0c;已被广泛应用于各个领域的科学研究以及工程计算&#xff0c;为工程界和科学界解决了复杂的多物理场建模问题。COMSOL内嵌的声学模块可以方便地进行多孔声学…

AI技术如何助力合同智能管理?

近年来&#xff0c;合同管理领域开始大规模应用AI技术&#xff0c;今天我们来关注下AI技术如何助力合同智能管理&#xff1f; 传统的合同管理系统&#xff0c;一般都是流程管理&#xff0c;随着AI技术的快速发展&#xff0c;AI技术已经成功应用到了合同全生命周期管理的各阶段…

计算机网络 三 (数据链路层)上

数据链路层 数据链路层的概述 基本概念 数据链路层是OSI参考模型中的第二层&#xff0c;它主要负责在物理层上提供可靠的数据传输服务&#xff0c;使得相邻节点间的数据传输能够实现。 数据链路层的基本概念如下&#xff1a; 帧&#xff1a;数据链路层数据传输的基本单位是…

Redis持久化:RDB和AOF(版本redis 7.0)

什么是持久化&#xff1f; 学过计算机基础的都知道以一种磁盘&#xff0c;只要关机&#xff0c;那么磁盘的内容都会被清空&#xff0c;这种磁盘称为内存&#xff0c;而Redis则是一种内存数据库&#xff0c;redis中的数据也都存储在磁盘中&#xff0c;如果服务器中进程被关掉&am…

麻了,真的不想做测试了...

前言 有不少技术友在测试群里讨论&#xff0c;近期的面试越来越难了&#xff0c;要背的八股文越来越多了,考察得越来越细&#xff0c;越来越底层&#xff0c;明摆着就是想让我们徒手造航母嘛&#xff01;实在是太为难我们这些测试工程师了。 这不&#xff0c;为了帮大家节约时…

Mathtype修改硕士论文公式格式

Mathtype修改硕士论文格式 1将word格式的公式变为mathtype格式1选中公式2点击mathtype中的转换公式 2修改mathtype格式的公式文字版式 1将word格式的公式变为mathtype格式 1选中公式 如果不选公式默认全文所有公式或者指定的公式。 2点击mathtype中的转换公式 选择要转换的…

汽车功能安全

前言 近些年来&#xff0c;功能安全在汽车传统底盘域和动力域的应用已较为成熟&#xff0c;各大汽车企业功能安全意识也逐渐增强。在辅助驾驶和自动驾驶爆发式增长的大趋势下&#xff0c;现代汽车的功能安全在目前尤为复杂的电子电气系统中就显得更为重要&#xff0c;功能安全…

MySQL---存储过程流程控制(判断(if、case)、循环(while、repeat、loop))

1. if判断 IF语句包含多个条件判断&#xff0c;根据结果为TRUE、FALSE执行语句&#xff0c;与编程语言中的if、else if、else 语法类似&#xff0c;其语法格式如下&#xff1a; -- 语法 if search_condition_1 then statement_list_1[elseif search_condition_2 then statem…

十八、Stream 流

目录 1、为什么要引入SpringCloud Stream 2、SpringCloud Stream简介 2.1、标准MQ架构图 2.2、SpringCloud Stream架构图 2.3、SpringCloud Stream处理流程 3、如何使用SpringCloud Stream 3.1、创建springcloud-stream-sender项目&#xff08;消息生产者&#xff09; …

SpringCloud_服务调用_Ribbon负载算法简介与如何替换(二)

SpringCloud_服务调用_Ribbon负载算法简介与如何替换(二) Ribbon核心组件IRule IRule:根据特定算法中从服务列表中选取一个要访问的服务 IRule接口有多种实现&#xff1a; Ribbon自带的7种负载规则 com.netflix.loadbalancer.RoundRobinRule 轮询 com.netflix.loadbalancer.Ra…

8年测试老鸟总结,软件测试工程师关键成长晋升要素,这些不能不知道...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、技术-依然是最…

MySQL深入浅出:自增长序列(@i:=@i+1)的用处及用法

目录 1&#xff1a;问题分析 2&#xff1a;模拟自增长序列 2.1 单表查询 2.2 多表关联查询 3&#xff1a;结束语 社区 1&#xff1a;问题分析 Oracle中的伪列 ROWNUM 是一组递增的序列&#xff0c;在查询数据时生成&#xff0c;为结果集中每一行标识一个行号, 每条记录…

医院运维场景下的风险感知

随着医疗信息化建设发展&#xff0c;医院的系统、设备不断叠加&#xff0c;在提升用户体验&#xff0c;享受高效医疗服务的同时&#xff0c;也为支撑系统稳定运行的信息部门带来巨大挑战。诸如科室复杂、应用场景多、终端运维工作量大、软件系统兼容需求强等痛点&#xff0c;并…

WPF MaterialDesign 初学项目实战(0):github 项目Demo运行

前言&#xff1a; 最近在学B站的WPF项目实战合集(2022终结版)&#xff0c;但是到22P时候发现UI框架 MaterialDesignThemes的Github上面的程序没办法正常运行&#xff0c;最后折腾了好久终于解决。 github地址 gitcode镜像地址 下载成功后 下载成功后是如下效果 打开这个文…

259元,诺基亚返祖式新机玩了把大的

智能手机经过这么多年发展&#xff0c;市场逐渐趋向成熟。 在这个过程中&#xff0c;优胜劣汰这一自然法则同样适用&#xff0c;无数没能经受住市场考验的企业也只能含泪离场。 其中最典型的例子还得是曾经手机中的王者诺基亚了。 当初在 Symbian&#xff08;塞班系统&#x…

php event原理以及对象与属性赋值

1、定义时间原理 2、定义对象与对象与属性赋值 ps:赋值过程其实会通过魔术方法_get调动本类的set方法 来源B站大佬视频 4.Yii2.0 Advanced Object与Property的关系_哔哩哔哩_bilibili

刚入职,就想跑路了...

刚入职一家公司&#xff0c;想离职又怕找不到新工作。 说实话&#xff0c;这个问题还是蛮常见的&#xff0c;很多时候&#xff0c;入职的公司并不是自己最满意的&#xff0c;即使是最满意的&#xff0c;入职后总会遇到各种各样的不顺心&#xff0c;公司制度不规范啊&#xff0…