【C++】——类和对象(初始列表,Static成员,友元)

4ea68a990b8b4ad5b754868032eee15d.jpeg

创作不易,多多支持! !😘😘

前言

因为前面的构造函数还有些地方不够清晰,所以这里需要再继续补充一些

一  初始化列表

1.1认识初始化

对于默认的构造函数来说,我们都知道它是起到了初始化的操作,但是它对于内置类型是不做处理的,所以一般初始化都需要我们主动去写,不然就算一堆随机值。下面就来看看构造函数初始化的具体步骤

我们还是拿日期类来说明

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
	Date()
	{}
	void Print()
	{
		cout << _year<<'-' << _month << '-' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
	
};
int main()
{
	Date d;
	d.Print();
	return 0;
}

以上代码就写了一个构造函数,其作用什么都不干,对于打印的结果就是一堆随机值 

347d35ef93a345abb095bb6567839c05.png

那我们改成我们常用的形式看看如何

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public:
	Date()
	{
		_year = 2024;
		_month = 4;
		_day = 27;
	}
	void Print()
	{
		cout << _year<<'-' << _month << '-' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
	
};
int main()
{
	Date d;
	d.Print();
	return 0;
}

很显然输出的答案就发生了变化

aa508c08c51343ce873143f86497a536.png

说这么多其实就是想表达一个点,这并不是初始化而是赋值

 因为初始化是在初始化列表实现的,函数体里只是赋值,所以这里要分清楚

对于真实性,我们可以调试来看看

6458ab5f8f89442b883fba033b9d0a7e.png

从图中我们可以看到的是,在进入构造函数里时,所有值都已经初始化成了随机值,后面的仅仅只是对这些内置类型赋值而已.

而对于初始化,就是由初始化列表提供的,因为我们没有显示的写出初始化列表,所以编译器就自动给了随机值。

1.2为什么要写初始化列表

对于上面的认识,可能就会觉得,为啥要初始化,直接让编译器初始化为随机值,我们后面再来赋值不就好了,其实不然。

对于以下类型必须得初始化

int& a;//引用

const int b;//const 类型

A   c;//没有默认构造的对象

以上类型必须得初始化,不然就会报错,所以就有初始化列表这个概念

 所有的内置类型都需要经过初始化列表

对于上面三个类型,必须放在初始化列表进行初始化,不然就会报错。

1.3 初始化的形式

那么对于初始化列表的基本形式应该是这样的

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

那对于上面的样例,我们可以照虎画猫有

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class A//A类
{
public:
	A(int a):m(a)
	{}
private:
	int m;
};


class Date//日期类
{
public:
	Date(A c,int& a):_a(a),_c(c),_b(10)
	{
		_year = 2024;
		_month = 4;
		_day = 27;
	}
	void Print()
	{
		cout << _year<<'-' << _month << '-' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
    //必须初始化的类型
	int& _a;
	const int _b;
	A _c;
};
int main()
{
	A c(1);
	int a = 0;
	Date d(c,a);
	return 0;
}

 注意:

1.所有变量的初始化只进行一次,但是赋值可以多次

2.初始化列表初始化的顺序是按照声明的顺序初始化的

 1.4  explicit 关键字 

构造函数不仅可以构造与初始化对象,对于接收单个参数的构造函数,还具有类型转换的作用。

对于单个参数的构造函数而言

有下面三种情况

1. 构造函数只有一个参数
2. 构造函数有多个参数,除第一个参数没有默认值外,其余参数都有默认值
3. 全缺省构造函数
class Date
{
public:
	 explicit Date(int year,int month=7,int day=21)
	{
		_year = 2024;
		_month = 4;
		_day = 27;
	}
	void Print()
	{
		cout << _year<<'-' << _month << '-' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2024)
	d1 = 2024;//这里其实发生了隐式类型转换
	return 0;
}

上面的代码是编译不过的,因为加了一个  explicit,它是阻止类型转换的。

一个整数赋值给一个对象,那么这个整数先转换成相同类型的对象,然后再赋值。

这里注意,如果有多个参数,上面的就会报错。

二  Static关键字

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

private:
	int _year;
	int _month;
	static int _day;//声明
};
int Date::_day = 20;//初始化

其中我们还需要注意的是

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

以上几点注意就行了,特别是第4点。

其实还有一个特例

private:
	int _year;
	int _month;
	const static int _day;//如果加入一个const,那么就可以不在类外面初始化
};

这个只对int类型有效,对于其他类型都是无效的

用static修饰以后,那么这个成员就是所有类共有的,所以可以直接用类名访问。

三  友元

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

3.1友元函数

友元函数就是在函数名前加上friend

 下面给出一个实例进行说明

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
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;
}

这段代码是对输入输出流的操作符进行了重载,使之可以输入对象,而不单单是内置类型

,那为什么要把这两个函数定义为友元呢?

 如果不定义为友元,那我们就得把这两个函数放到类里面去才能访问到私有的成员变量,那么又有一个问题就来了。

767ea9b58a31456da1bbfb8c287c68c0.png

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

 友员函数不是成员函数,所以不能被const修饰,这一点要注意。

3.2  友元类

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

定义了友元类,比如B是A的友元,那么B可以访问A的所有成员,但是A不能访问B的成员,比较自私 

内部类

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

 其实就是跟友元类是差不多的,只不过友元类打破了封装性,但是内部类使封装更加好。

以上就是关于对构造函数的一些补充还有其他知识点的说明,如果看到这里对你有帮助,那支持一些吧😍😍😍 

3bb809f83d744bf3961a43f5452ba6ab.png

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

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

相关文章

3-4STM32C8T6按键控制LED开与关

实物接线如下&#xff1a; 为了代码的简洁性&#xff0c;这里需要对LED与KEY进行封装如下&#xff1a; #include "stm32f10x.h" // Device headervoid LED_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GP…

WSL2-Ubuntu使用Conda配置百度飞浆paddlepaddle虚拟环境

0x00 缘起 本文将介绍在WSL2-Ubuntu系统中,使用Conda配置百度飞浆paddlepaddle虚拟环境中所出现的各种问题以及解决方法,最终运行"run_check()"通过测试。 在WSL2中配置paddlepaddle不像配置Pytorch那样顺滑,会出现各种问题(如:库的文件缺失、不知道如何匹配C…

工厂模式和策略模式区别

工厂模式和策略模式都是面向对象设计模式&#xff0c;但它们的目的和应用场景有所不同。 工厂模式是一种创建型设计模式&#xff0c;旨在通过使用一个工厂类来创建对象&#xff0c;而不是直接使用new关键字来创建对象。这样做可以使系统更容易扩展和维护&#xff0c;因为新的对…

模型智能体开发之metagpt-单智能体实践

需求分析 根据诉求完成函数代码的编写&#xff0c;并实现测试case&#xff0c;输出代码 代码实现 定义写代码的action action是动作的逻辑抽象&#xff0c;通过将预设的prompt传入llm&#xff0c;来获取输出&#xff0c;并对输出进行格式化 具体的实现如下 定义prompt模版 …

Cisco IOS XE Web UI 权限提升漏洞复现(CVE-2023-20198)

0x01 产品简介 Web UI 是一种基于GUI的嵌入式系统管理工具,能够提供系统配置、简化系统部署和可管理性以及增强用户体验。它带有默认映像,因此无需在系统上启用任何内容或安装任何许可证。Web UI 可用于构建配置以及监控系统和排除系统故障,而无需CLI专业知识。 0x02 漏洞…

redis 高可用 Sentinel 详解

写在前面 redis 在我们日常的业务开发中是十分常见的&#xff0c;而redis的可用性就必须要有很高的要求&#xff0c;那么 redis集群的高可用由有一个或者多个 Sentinel(哨兵) 实例组成的 哨兵系统来保证的。 哨兵 由一个或者多个 Sentinel 实例组成的 Sentinel 系统可以监控任…

Java项目:基于SSM框架实现的高校专业信息管理系统设计与实现(ssm+B/S架构+源码+数据库+毕业论文+PPT+开题报告)

一、项目简介 本项目是一套基于SSM框架实现的高校专业信息管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

Python3.11修改并运行oneforall

遇到的问题 使用python3.11默认无法运行oneforall脚本&#xff0c;出现如下报错 # 解决方案 修改 /usr/local/lib/python3.11/dist-packages/exrex.py exrex.py具体文件路径报错中会显示 vim /usr/local/lib/python3.11/dist-packages/exrex.py# 修改前 from re import sre…

基于Hyperf的CMS,企业官网通用php-swoole后台管理系统

2023年9月11日10:47:00 仓库地址&#xff1a; https://gitee.com/open-php/zx-hyperf-cms CMS&#xff0c;企业官网通用PHP后台管理系统 框架介绍 hyperf SCUI 后端开发组件 php 8.1 hyperf 3.1 数据库 sql(使用最新日期文件) hyperf\doc\sql_bak mysql 8. 系统默认账号…

微软如何打造数字零售力航母系列科普05 - Azure中计算机视觉的视觉指南

Azure中计算机视觉的视觉指南 什么是计算机视觉&#xff1f;如何使用Microsoft Azure将计算机视觉功能集成到应用程序和工作流中&#xff1f; 作者&#xff1a;Nitya Narasimhan 编辑&#xff1a;数字化营销工兵 •11分钟阅读 什么是计算机视觉&#xff1f;如何使用Microso…

最快成型的前端框架Layuimini本地项目部署演示

最快成型的前端框架Layuimini本地项目部署演示 本篇以LayuiMini-v2在线页面预览为例 点击上述链接跳转页面 1. 准备工作 环境准备 WindowsNginxWeb项目资源包&#xff08;Layuimini-v2&#xff09; 2. 页面加载 拉取到本地后直接访问时会出现如下弹窗&#xff0c;无法加载页…

LeetCode LCR 179. 和为s的两个数字

原题链接&#xff1a;LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09; 题目的意思&#xff1a;通过给定的数组&#xff0c;找出两个值&#xff0c;相加并等于目标值。 第一种思路&#xff0c;暴力枚举&#xff0c;伪代码如下&#xff1a; for (…

暴雨服务器引领信创算力新潮流

去年大模型的空前发展&#xff0c;人工智能也终于迎来了属于自己的“文艺复兴”&#xff0c;众多的模型相继发布&#xff0c;继而催生了整个行业对于智能算力需求的激增。 市场需求与技术驱动仿佛现实世界的左右脚&#xff0c;催动着世界文明的齿轮向前滚动。在全球经济角逐日…

【计算机网络】FTP站点配置搭建教程以及相关问题解决方案(超详细)

文章目录 1、安装Window Server 20082、搭建FTP环境&#xff08;1&#xff09;安装FTP服务器&#xff08;2&#xff09;配置FTP服务器&#xff08;3&#xff09;测试FTP连接 3、遇到的问题以及解决方案&#xff08;1&#xff09;Windows无法访问此文件夹&#xff08;2&#xff…

如何将安卓手机投屏到Windows 10电脑上

诸神缄默不语-个人CSDN博文目录 我之所以要干这个事是为了用手机直播的时候在电脑上看弹幕…… 文章目录 1. 方法一&#xff1a;直接用Win10内置的投影到此电脑2. 方法二&#xff1a;用AirDroid Cast投屏到电脑上 1. 方法一&#xff1a;直接用Win10内置的投影到此电脑 在设置…

抓取应用程序sql语句

一、利用tcpdump和wireshark 抓包方法 1、下载安装wireshark&#xff08;windows用&#xff09; 注&#xff1a;可以用wireshark 抓包和分析包 https://www.wireshark.org/ 2、安装tcpdump&#xff08;linux用&#xff09; yum install tcpdump -y3、在数据库服务器上抓数据…

java-链表排序

需求 思路 排序&#xff1a;讲所有的值都取出来&#xff0c;存储到ArrayList中&#xff0c;然后排序&#xff0c;将排序之后的元素依次使用add方法添加到自定义链表合并排序&#xff1a;先合并&#xff0c;然后调用刚才写的排序算法合并&#xff1a;将表一的头结点作为新链表的…

CUDA内存模型

核函数性能并不只与线程束的执行有关。 CUDA内存模型概述 GPU和CPU内存模型的主要区别是&#xff0c;CUDA编程模型能将内存层次结构更好地呈现给用户&#xff0c;能让我们显示的控制它的行为。 对程序员来说&#xff0c;一般有两种类型的存储器&#xff1a; 可编程的&#x…

【docker 】 IDEA 安装 Docker 工具

打开File->Settings->Plugins 配置 Docker 的远程访问连接 Engine APIURL &#xff1a;tcp://192.168.0.1:2375 &#xff08;换成自己的docker开放端口&#xff09; 使用diea的docker插件 查看已有的镜像 创建一个容器 下面是最近更新的文章&#xff1a; 【docker 】 …

异地组网,让“远程运维”更简单

您是否在联网场景中有过这些需求&#xff1f; 摄像头需要联网统一监控、PLC需要联网告别本地升级、工控机需要联网告别本地配置、广告屏需要联网告别本地下载视频、远程打开终端设备WEB进行配置......这些问题有人新升级的“异地组网”功能统统可以解决&#xff01; 告别繁琐…