C++初阶学习第五弹——类与对象(下)——类与对象的收官战

 类与对象(上):C++初阶学习第三弹——类与对象(上)——初始类与对象-CSDN博客

类与对象(中):C++初阶学习第四弹——类与对象(中)——刨析类与对象的核心点-CSDN博客

前言:

在前面我们已经学习了C++类与对象的关键操作——默认成员函数,今天我们对之前的内容进行一些补充,同时再来学习几个新的知识点Static成员、友元和内部类

目录

一、构造函数进阶

1.1 构造函数的赋值化

1.2 构造函数的初始化

1.3 explicit关键字

二、static成员

三、友元

3.1 友元函数

3.2 友元类

四、内部类

五、总结


一、构造函数进阶

1.1 构造函数的赋值化

在前面,我们说对一个自定义类型的变量,当我们定义时可以通过构造函数默认初始化,操作如下:

class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1();
	return 0;
}

实际上这样的操作并不叫作初始化,更确切的说应该叫赋值化,因为初始化只能有一次,而这个操作却可以多次赋值

比如:

	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
		_year = 3;
	}

这里就对_year进行了两次赋值,所以这个操作不能称之为初始化,而应该称之为赋值

1.2 构造函数的初始化

构造函数的初始化应该是这样一种形式:

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year),
		_month(month),
		_day(day)
	{

	}	
private:
	int _year;
	int _month;
	int _day;
};

有这样几个注意事项:

1、类中成员初始化时一定要按照它们声明的顺序来进行,尽量不要跳跃

2、每个成员只能在初始化列表中出现一次(初始化只能是一次)

3、类中包含以下成员,必须放在初始化列表位置进行初始化:

     ·  引用成员变量

     ·  const成员变量

     ·  自定义类型成员(且该类没有默认构造函数时)

上面提到的一定要注意对于引用成员变量、const成员变量、自定义类型成员一定要在初始化列表中进行初始化:

class A
{
public:
	A(int a)
		:_a(a)
	{}
private:
	int _a;
};
class B
{
public:
	B(int a, int ref)
		:_aobj(a)
		, _ref(ref)
		, _n(10)
	{}
private:
	A _aobj; // 没有默认构造函数
	int& _ref; // 引用
	const int _n; // const 
};

1.3 explicit关键字

对于接受单个参数的构造函数,不仅具有初始化的功能,还具有隐式转换的功能

下面这三种都属于只接受单个参数的:

1、构造函数只有一个参数

2、构造函数有多个参数,但是只有一个没有默认值

3、全缺省构造函数

class Date
{
public:
	// 1. 单参构造函数,没有使用explicit修饰,具有类型转换作用
	// explicit修饰构造函数,禁止类型转换---explicit去掉之后,代码可以通过编译
	explicit Date(int year)
		:_year(year)
	{}
	/*
	// 2. 虽然有多个参数,但是创建对象时后两个参数可以不传递,没有使用explicit修饰,具有类型转
   换作用
	// explicit修饰构造函数,禁止类型转换
	explicit Date(int year, int month = 1, int day = 1)
	: _year(year)
	, _month(month)
	, _day(day)
	{}
	*/
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
void Test()
{
	Date d1(2022);
	// 用一个整形变量给日期类型对象赋值
	// 实际编译器背后会用2023构造一个无名对象,最后用无名对象给d1对象进行赋值
	d1 = 2023;
	// 将1屏蔽掉,2放开时则编译失败,因为explicit修饰构造函数,禁止了单参构造函数类型转换的作
//	用
}

二、static成员

static修饰的成员变量就是类中的静态成员变量,static修饰的成员函数就是静态成员函数

我们需要注意的是静态成员变量一定要在类外进行初始化

class A
{
private:
	static int _a;
};

//在类外对_a进行初始化
int A::_a = 0;

int main()
{
	return 0;
}

注意事项:

1、静态成员存放在静态区,为所有类成员共享

2、静态成员必须在类外定义(初始化),类中只是声明

3、静态成员访问方式:类名::静态成员或者对象.静态成员

三、友元

友元是一种突破类封装的一种方法,在特定的情况下使用会有意想不到的好处,但是类存在的意义就是进行封装,所以友元的使用会破坏耦合性,所以我们平时要尽量减少使用友元

友元有两种:友元类和友元函数

3.1 友元函数

对于一些函数而言,并不适合将它封装在类中,比如operator<<流输出函数

我们一般是这样用这个函数的:

int main()
{
	cout << d1 << endl;
	return 0;
}

而在将这个函数写在类中的时候,由于类中函数this指针默认的是第一个操作数(也就是左操作数),所以这样输出是不行的

需要这样才能保证:

int main()
{
	d1 << cout;
	//或者
	d1.cout;
	return 0;
}

但这样又违背常理,所以我们往往就需要在类外写一个全局函数来实现这个功能,但是在类外的话就不能直接访问类中的私有化成员,所以就有了友元函数的出现

友元函数实现上述功能的操作如下:

class Date
{
	friend ostream& operator<<(ostream& _cout, const Date& d);
	friend istream& operator>>(istream& _cin, Date& d);
public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

private:
	int _year;
	int _month;
	int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{
	_cout << d._year << "-" << d._month << "-" << d._day;
	return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{
	_cin >> d._year;
	_cin >> d._month;
	_cin >> d._day;
	return _cin;
}
int main()
{
	Date d;
	cin >> d;
	cout << d << endl;
	return 0;
}

3.2 友元类

友元类跟上面的友元函数很想,也是间接访问一个类中私有化成员的一种方法

比如一个时间类Time和一个日期类Date,我们就可以通过在时间类中声明日期类为时间类的友元类从而直接访问时间类中的私有成员变量

class Time
{
	friend class Date;     //声明Date为友元类
private:
	int _hour;
	int _min;
};
class Date
{
public:
	void test(int hour, int min)
	{
		_t._hour = hour;       //可以在Date类中直接引用Time类私有成员变量
		_t._min = min;
	}
private:
	int _year;
	int _month;
	int _day;
	Time _t;
};

四、内部类

如果一个类定义在另一个类的内部,那么这个类就叫做那个类的内部类

重点:

1、内部类和外部类实际上还是两个完全独立的类,完全可以将它们两个分开写

2、内部类是外部类的友元类,可以访问外部类的私有成员,但外部类不是内部类的友元类

3、内部类可以直接访问外部类的静态成员,不需要外部类的对象名或者类名

例如:

class A
{
public:
	class B
	{
	public:
		void Test(const A& a)
		{
			cout << k << endl;    //静态变量可以直接访问
			cout << a.h << endl;
		}
	};
private:
	static int k;
	int h;
};
int A::k = 1;
int main()
{
	A::B b;
	b.Test(A());
	return 0;
}

运行结果:

五、总结

以上就是C++类与对象的全部内容了,这三期基本就把类与对象所有知识点全部囊括了,如果有不理解的地方,欢迎在评论区中指出或者与我私信交流!!!

感谢各位大佬观看,创作不易,还请各位大佬点赞支持!!!

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

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

相关文章

Linux环境下的事件驱动力量:探索Libevent的高性能I/O架构

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之《Linux环境下的事件驱动力量&#xff1a;探索Libevent的高性能I/O架构》&#xff0c;在这篇文章中&#xff0c;你将会学习到Libevent的高性能I/O原理以及应用&#xff0c;并且我会给出源码…

云仓酒庄携手央视共筑品牌新高度,酒类行业广告战略迈向新征程

随着酒类市场的日益繁荣与竞争的加剧&#xff0c;品牌宣传与推广在酒类行业中的地位愈发凸显。近日&#xff0c;云仓酒庄宣布与中视中州&#xff08;央视代理机构&#xff09;达成2024-2025年度央视广告战略合作&#xff0c;云仓酒庄副总裁周玄代表云仓酒庄签约&#xff0c;这一…

Ubuntu系统安装nvfortran详细步骤【笔记】

实践设备&#xff1a;华硕FX-PRO&#xff08;NVIDIA GeForce GTX 960M&#xff09; Ubuntu系统安装NVFORTRAN&#xff08;NVIDIA Fortran Compiler&#xff09;步骤如下&#xff1a; 安装依赖项&#xff1a;在安装NVFORTRAN之前&#xff0c;你需要确保系统已经安装了一些必要…

Linux学习(一)-- 简单的认识

目录 1. Linux的诞生 2.Linux发行版 拓展&#xff1a; &#xff08;1&#xff09;什么是Linux系统的内核&#xff1f; &#xff08;2&#xff09;什么是Linux系统发行版&#xff1f; 1. Linux的诞生 Linux创始人: 林纳斯 托瓦兹 Linux 诞生于1991年&#xff0c;作者上大学…

Java特性之设计模式【享元模式】

一、享元模式 概述 享元模式&#xff08;Flyweight Pattern&#xff09;主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能。这种类型的设计模式属于结构型模式&#xff0c;它提供了减少对象数量从而改善应用所需的对象结构的方式 享元模式尝试重用现有的同类对…

LeetCode 226.翻转二叉树(全网最多的解法)

LeetCode 226.翻转二叉树 1、题目 题目链接&#xff1a;226. 翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#…

Unity 性能优化之遮挡剔除(Occlusion Culling)(六)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、遮挡剔除是什么&#xff1f;二、静态遮挡剔除的使用步骤1.标记为遮挡剔除对象2.创建Occlusion Area组件3.烘焙4.Occlusion窗口Bake的参数Smallest Oc…

MYSQL基础架构、执行过程分析、事务的实现、索引的选择、覆盖索引

本文是mysql45讲的1-5的总结 文章目录 基础架构连接器分析器优化器执行器SQL查询执行过程详细执行步骤 SQL更新执行过程重要的日志模块&#xff1a;redo log重要的日志模块&#xff1a;binlog阶段性提交 事务事务隔离的实现启动 索引数据库索引模型InnoDB索引组织结构主键选择…

[Unity常见小问题]打包ios后无法修改模型透明度

问题 在Editor下可以使用如下代码去修改模型的材质的透明度&#xff0c;但是打包ios后无法对透明度进行修改且没有任何warning和error using System.Collections; using System.Collections.Generic; using UnityEngine;public class NewBehaviourScript : MonoBehaviour {[R…

订票系统|基于Springboot+vue的火车票订票系统(源码+数据库+文档)

订票系统目录 基于Springbootvue的火车票订票系统 一、前言 二、系统设计 三、系统功能设计 1会员信息管理 2 车次信息管理 3订票订单管理 4留言板管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍…

【RAG 论文】SKR:Self-Knowledge 指导下的 RAG

论文&#xff1a;Self-Knowledge Guided Retrieval Augmentation for Large Language Models ⭐⭐⭐⭐ Tsinghua, arXiv:2310.05002 文章目录 一、论文速读二、实现细节2.1 数据的收集2.2 引出 LLM 的 Self-Knowledge 的方法1&#xff09;Direct Prompting2&#xff09;In-Cont…

正则将段落分割成句子

这里分割段落不区分中英文标点&#xff0c;你可以根据需求改 分割后标点跟随句子后面 def split_sentences_keep_delimiter(text):pattern r[^。!&#xff01;?&#xff1f;:&#xff1a;;&#xff1b;,&#xff0c;][。!&#xff01;?&#xff1f;:&#xff1a;;&#xff…

记录DemoApplication.java不变蓝问题

问题 解决方案 一、点击右下角加载 二、右键项目 勾选maven

计算机毕设

随着社会和国家的重视&#xff0c;大学对于大学生毕业设计越来越重视。 做软件设计设计方面&#xff0c;前后端分离是必不可少的&#xff0c;代码管理工具&#xff0c;前后端接口测试是项目中必须要用到的工具。做大数据设计方面&#xff0c;主要是要用到爬虫进行数据爬取&…

多选择性更容易理解!基于可选择性遗传算法的微电网经济-低碳协调优化程序代码!

前言 随着能源危机和环境污染日益严重&#xff0c;传的能源已不再满足人们日益增长的能源需求&#xff0c;丰富清洁的可再生能源是未来的发展方向&#xff0c;分布式可再生能源发电技术获得了飞速进步。然而&#xff0c;在引入分布式可再生电源后&#xff0c;微电网的复杂性以…

音频智能切换器JR-AR42-A

憬锐JR-AR42-A音频自动智能切换器(四切一)&#xff0c;具备四路模拟卡侬立体声音频输入&#xff0c;两路模拟卡侬立体声音频输出&#xff0c;其中输入第1路和输出第1路为断电直通通道。具有输入音频信号幅度判别&#xff0c;可设置门限电平和切换延时时间&#xff0c;可以根据需…

通信系列:通信中如何度量消息中所包含的信息量?如何评估通信系统的性能?

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、通信中如何度量消息…

代码随想录训练营31day-动态规划4

一、完全背包&#xff08;参考博客&#xff09; 和01背包区别在于物品可以无限次放入背包。完全背包和01背包问题唯一不同的地方就是&#xff0c;每种物品有无限件。 因此在需要在遍历顺序上进行区别&#xff0c;参考代码随想录&#xff1a; 二、518.零钱兑换II 题目求的是组…

ASP.NET网上图书预约系统的设计

摘 要 《网上图书预约系统的设计》是以为读者提供便利为前提而开发的一个信息管理系统&#xff0c;它不仅要求建立数据的一致性和完整性&#xff0c;而且还需要应用程序功能的完备、易用等特点。系统主要采用VB.NET作为前端的应用开发工具&#xff0c;利用SQL Server2000数据…

初识指针(2)<C语言>

前言 前文介绍完了一些指针基本概念&#xff0c;下面介绍一下&#xff0c;const关键字、指针的运算、野指针的成因以及避免&#xff0c;assert函数等。 目录 const&#xff08;常属性&#xff09; 变量的常属性 指针的常属性 指针的运算 ①指针 -整数 ②指针-指针 ③指针与…
最新文章