c++ - 类与对象 - explicit关键字 | static成员 | 友元 | 内部类 | 匿名对象

news2024/12/23 9:45:45

文章目录

    • 一、 explicit关键字
    • 二、static成员
    • 三、友元
    • 四、内部类
    • 五、匿名对象


一、 explicit关键字

1、隐式类型转换
再进行隐式类型转换是会产生一个临时变量tmp,再用临时变量进行赋值。

如:

double d = 1.2;
//再用 d 给 i 进行赋值时,会进行隐式类型转换。
//过程:产生 tmp  = 1 ,再用 tmp 给 i 进行赋值
int i = d;

在这里插入图片描述

那么对于类来说是否也能进行这样的隐式类型转换呢?
答:是的,比如 int 转为 类 , 先用 int i 进行转换为 类类型 A(这个过程会调用构造函数进行构造出一个临时类(tmp)),再用 tmp 拷贝到 A 即完成了隐式类型转换。

如:

class A
{
public:
	//有参构造
	A(int a)
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}

	//拷贝构造
	A(const A & a)
	{
		cout << "A(const A & a)" << endl;
	}
private:
	int _a;

};

int main()
{
	A aa = 3;
	//等价与  A tmp(3) , A aa = tmp; 
	//先将 3(int) 隐式转换为 自定义类型 A (tmp),再aa = tmp (拷贝构造)

	return 0;
}

在这里插入图片描述
在这里插入图片描述
上面演示的是单参数的隐式转换,下面是多参数的隐式转换

//多参数隐式类型转换
class A
{
public:
	//有参构造  多参数
	A(int a,int b)
		:_a(a)
		,_b(b)
	{
		cout << "A(int a)" << endl;
	}
private:
	int _a;
	int _b;
};

int main()
{
	//调用格式 ,也可 aa{1,2},但是不建议这种
	A aa = { 1,2 };
	return 0;
}

补充:
临时变量具有常量性。

int main()
{
	double d = 1.12;

	//int i = d; 正常进行隐式转换

	//int& i = d;	//引用临时变量  过程 const int tmp -> int &i = tmp 但是tmp是常量所以会报错 

	//正确做法	//临时变量如果被引用生命周期会延长,不然用完就销毁了
	const int& i = d;
	return 0;
}

在这里插入图片描述

2、如果不想要编译器进行隐式类型转换呢?
使用 explicit 关键字 就可以了
如:

explicit A(int a,int b)
	:_a(a)
	,_b(b)
{
	cout << "A(int a)" << endl;
}

二、static成员

1、概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化。

class A
{
public:
	//静态成员函数
	static void Print()
	{
		cout << _a << endl;
	}

private:
	//静态成员变量
	static int _a;
};

//在类外定义
int A::_a = 10;

2、static成员的特征

(1). 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
(2). 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
(3). 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
(4). 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
(5). 静态成员也是类的成员,受public、protected、private 访问限定符的限制

class A
{
public:
	//静态成员函数
	static void Print()
	{
		cout << _a << endl;
		//静态函数不能访问非静态成员
		//cout << _b << endl;
	}

	//静态成员变量  声明
	static int _a;
	int _b = 10;
};

//在类外定义
int A::_a = 10;

int main()
{
	A a1;
	cout << sizeof(a1) << endl; // 大小为 4 ,_a 存在静态区

	A a2;
	cout << "直接通过类来访问" << A::_a << endl;
	cout << "a1:" << a1._a << endl;		// a1._a == a2._a 这个成员变量共享
	cout << "a2:" << a2._a << endl;		//当前在公共区域,当设置为私有时对象就不可访问了

	return 0;
}

在这里插入图片描述

3、静态和非静态的区别

1、调用方式:
非静态成员函数:需要通过类的实例来调用。
静态成员函数: 可以通过类名直接调用,也可以通过实例调用。
2. 访问成员:
非静态成员函数: 可以访问类的实例中的非静态成员变量和其他成员函数。
静态成员函数: 不能直接访问类的实例成员,只能访问类的静态成员变量和其他静态成员函数。
3. this指针:
非静态成员函数: 隐含地有一个指向当前对象的指针(this指针)。
静态成员函数: 没有this指针,因为它与特定的实例无关。

三、友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

关键字:friend

1、友元函数
友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

(1)如:重载 << 操作符
我们知道 重载 << 操作符时,不能定义为成员函数,所以只能使用全局函数了,但是类的成员变如果是私有的,对象就无法访问成员变量了,这时使用友元函数就可以很好解决这个问题。

class A
{
	//声明友元函数
	friend ostream& operator<<(ostream& _cout, A& a);
public:


private:
	int _a = 10;
};

ostream& operator<<(ostream& _cout, A &a)
{
	//作为友元函数来访问私有成员
	_cout << a._a << endl;
	return _cout;
}

(2)友元函数的特征

a. 友元函数可访问类的私有和保护成员,但不是类的成员函数。
b. 友元函数不能用const修饰。
c. 友元函数可以在类定义的任何地方声明,不受类访问限定符限制。
d. 一个函数可以是多个类的友元函数。
e. 友元函数的调用与普通函数的调用原理相同。

2、友元类

(1)友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
(2)友元关系是单向的,不具有交换性。
(3)友元关系不能传递 如果C是B的友元, B是A的友元,则不能说明C时A的友元。
(4)友元关系不能继承。

class B;
//友元类
class A
{
	//B 类作为 A类的友元
	friend class B;
public:
	void Print(B& b)
	{
		//A类不可以访问B类 ,不具有交换性
		//cout << b._b << endl;
	}
	

private:
	int _a = 10;
};

class B
{
	friend class C;
public:
	void Print(A& a)
	{
		//可以访问非公有成员
		cout << a._a << endl;
	}
private:
	int _b = 10;
};

class C
{
public:
	void Print(A& a)
	{
		//友元关系不能传递,这里无法访问到A类的非公有成员
		//cout << a._a << endl;
	}
};

四、内部类

1、概念

如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限,但是内部类就是外部类的友元类。

2、特征

(1). 内部类可以定义在外部类的public、protected、private都是可以的,但是也会受到这些作用符限定。
(2)注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
(3) sizeof(外部类)=外部类,和内部类没有任何关系。

//内部类
class A
{
public:
	//B类 默认作为 A类友元
	class B
	{
	public:
		void P(A& a)
		{
			//可以直接访问a的非公有成员
			cout << a._a << endl;

			//可以直接访问A类的静态成员
			cout << s_a << endl;
		 }

	private:
		int _b = 10;

	};



private:
	int _a = 10;
	static int s_a;
};
int A::s_a = 20;


int main()
{
	A a;

	cout << "A类的大小:" << sizeof(a) << endl; //4,不受到B类的干扰

	//使用B类
	A::B  b;

	//访问b类成员函数
	b.P(a);

	return 0;
}

在这里插入图片描述

五、匿名对象

//匿名对象
class A
{
public:
	A(int a = 10)
		:_a(a) 
	{}
	int get()
	{
		return _a;
	}

private:
	int _a;

};

int main()
{
	//正常实例化对象  生命周期从定义到main函数结束
	A a1;
	A a2(10);

	//匿名对象	生命周期仅仅就是定义这行
	A();
	A(10);

	//一些作用如:想调用非静态成员函数

	//用匿名对象
	A().get();	

	//一般用法  ,比匿名对象繁琐
	A a3;
	a3.get();

	return 0;

}

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

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

相关文章

面向对象设计与分析40讲(25)中介模式、代理模式、门面模式、桥接模式、适配器模式

文章目录 门面模式代理模式中介模式 之所以把这几个模式放到一起写&#xff0c;是因为它们的界限比较模糊&#xff0c;结构上没有明显的差别&#xff0c;差别只是语义上。 这几种模式在结构上都类似&#xff1a; 代理将原本A–>C的直接调用变成&#xff1a; A–>B–>…

探索RadSystems:低代码开发的新选择(二)

系列文章目录 探索RadSystems&#xff1a;低代码开发的新选择&#xff08;一&#xff09;&#x1f6aa; 文章目录 系列文章目录前言一、RadSystems Studio是什么&#xff1f;二、用户认证三、系统角色许可四、用户记录管理五、时间戳记录总结 前言 在数字化时代&#xff0c;低…

HoloLens2的Unity应用在电脑上发布成安装包,然后通过wifi安装到设备

一、VS工程中的鼠标右键 二、发布——>创建应用程序包 三、选择【旁加载】 四、选择签名方法&#xff1a; 五、选择和配置包 六、创建完毕 七、网络连接设备 八、登录设备 九、安装app

基于springboot实现的摄影跟拍预定管理系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven…

OpenHarmony实战开发-合理选择条件渲染和显隐控制。

开发者可以通过条件渲染或显隐控制两种方式来实现组件在显示和隐藏间的切换。本文从两者原理机制的区别出发&#xff0c;对二者适用场景分别进行说明&#xff0c;实现相应适用场景的示例并给出性能对比数据。 原理机制 条件渲染 if/else条件渲染是ArkUI应用开发框架提供的渲…

实现Spring底层机制(阶段1—编写自己的Spring容器,扫描包,得到bean的Class对象)

环境搭建抛出问题 1.环境搭建 1.创建maven项目 2.导入依赖 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://maven.ap…

RK3568 学习笔记 : u-boot 通过 tftp 网络更新 u-boot自身

前言 开发板型号&#xff1a; 【正点原子】 的 RK3568 开发板 AtomPi-CA1 使用 虚拟机 ubuntu 20.04 收到单独 编译 RK3568 u-boot 使用 rockchip Linux 内核的设备树 【替换】 u-boot 下的 rk3568 开发板设备树文件&#xff0c;解决 u-boot 下千兆网卡设备能识别但是无法 Pi…

MQTT服务器EMQX的安装和使用(Windows)

一、下载地址&#xff1a; 下载 EMQX 二、安装环境&#xff1a; Windows Server2016 16G 500G 三、启动服务&#xff1a; 下载文件解压后放入以下目录&#xff08;注意&#xff0c;目录名一定是英文&#xff0c;否则会造成启动不成功&#xff01;&#xff09;&#xff1a…

Linux部署Coturn以及关于打洞的思考

目录 Coturn介绍部署架构图 2.1 局域网——无NAT映射 2.2 NAT网Corturn安装步骤验证 4.1 局域网——无NAT映射 4.2 NAT网 4.2.1 Cywin安装步骤 4.2.2 Coturn安装步骤 4.2.3 验证引言 下文部署架构图为Corturn为解决互联网NAT环境下“找朋友”的部署架构,也是Coturn发挥其价值…

C# 给图片添加文字水印

目录 应用场景 开发运行环境 方法说明 方法代码 调用示例 小结 应用场景 在某些应用项目&#xff08;如电子档案信息管理&#xff09;中&#xff0c;查看电子图片信息是经常使用到的功能&#xff0c;此时我们就需要给显示在浏览器中的图片添加文字水印版权或提示信息。…

Oracle EBS Interface/API(54)- GL日记账审批

背景: 客户化创建薪酬凭证或者银企付款入账日记账以后,用户希望自动提交审批流程,无需到系统标准功能点击审批,减少用户操作。 快速参考 参考点内容功能导航N: GL->日记账->输入并发请求None基表GL.GL_JE_BATCHESAPI参考下面介绍错误信息表None接口FormNone接口Reque…

PLSQL数据库

目录 什么是PLSQL数据库 PL数据库的实现方法 PL数据库的基本语法 1.作用 2.语法 3.赋值输出 4.引用 5.异常处理 6.if 判断 7.loop循环 8.while循环 9.for循环 10.游标 11.参数游标 12.索引 13.分区表 什么是PLSQL数据库 PL/SQL&#xff08;Procedure Language/…

mysql虚拟列问题

1&#xff0c;虚拟列的用途 1.1&#xff0c;虚拟列可以在创建表时定义&#xff0c;并在查询时像普通列一样使用&#xff1b;方便查询数据&#xff1b;比如从复杂的列数据中&#xff0c;解析taskID&#xff0c;使用虚拟列就很方便&#xff1b; 1.2&#xff0c;mapvalue是txt类…

查理·芒格的 100 个思维模型是什么?一文弄懂多元思维模型!

查理芒格&#xff0c;全名查尔斯托马斯芒格&#xff0c;是一位美国投资者、商业人士以及慈善家。他最为人所知的身份是作为伯克希尔哈撒韦公司的副主席&#xff0c;与投资大师沃伦巴菲特共同塑造了该公司的投资风格和成功。芒格以其深厚的智慧、跨学科的思考方式和独到的价值投…

vivado 使用波形 ILA 触发器和导出功能

使用波形 ILA 触发器和导出功能 • 启用自动重新触发 &#xff1a; 选中“ Waveform ”窗口工具栏上的“启用自动重新触发 (Enable Auto Re-Trigger) ”按钮即可在 成功完成触发 上传 显示操作后 &#xff0c; 启用 Vivado IDE 以自动重新装备与“ Waveform ”窗口触发器…

自动化软件测试用例,自动化测试用例设计

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

书生·浦语大模型第二期实战营(5)笔记

大模型部署简介 难点 大模型部署的方法 LMDeploy 实践 安装 studio-conda -t lmdeploy -o pytorch-2.1.2conda activate lmdeploypip install lmdeploy[all]0.3.0模型 ls /root/share/new_models/Shanghai_AI_Laboratory/ln -s /root/share/new_models/Shanghai_AI_Laborato…

浏览器不兼容的问题和通用解决方案

大家好&#xff0c;我是咕噜铁蛋&#xff0c;今天我想和大家聊聊一个在我们日常上网过程中经常遇到的问题——浏览器不兼容。这个问题看似微小&#xff0c;但却常常让我们在浏览网页、使用在线应用时感到困扰。接下来&#xff0c;我将详细分析浏览器不兼容的原因&#xff0c;并…

【雪天鱼】Vitis HLS 学习笔记(1) Pipelining 流水线

文章目录 1 自媒体账号2 Pipelining 流水线2.1 只对最内层的 LOOP_J 循环进行 pipeline2.2 对最外层的 LOOP_I 循环进行 pipeline2.3 对函数 loop_pipeline 进行 pipeline&#xff0c;并对数组A进行分组2.4 思考 1 自媒体账号 目前运营的自媒体账号如下&#xff1a; 哔哩哔哩…

【uniapp】【uview2.0】【u-sticky】Sticky 吸顶

把pages.json文件中的 “navigationStyle"设置为"custom”, 出现的问题是&#xff0c;莫名奇妙多了个 一个高度 解决方法 /* 使用CSS的sticky定位 */ .sticky {/* #ifdef H5 */ position: -webkit-sticky;position: sticky;top: 0; /* 设置距顶部的距离 */z-ind…