C++:初始化列表,static成员,友元,内部类

news2024/11/26 0:33:47

在这里插入图片描述

个人主页 : 个人主页
个人专栏 : 《数据结构》 《C语言》《C++》

文章目录

  • 前言
  • 一、初始化列表
  • 二、static成员
  • 三、友元
  • 四、内部类
  • 总结


前言

本篇博客作为C++:初始化列表,static成员,友元,内部类的知识总结。


一、初始化列表

初始化列表:以冒号开始,接着是一个以逗号分隔的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或表达式。
在这里插入图片描述


  • 初始化列表是每个成员变量定义的地方
  • 每个成员变量在初始化列表中只能出现一次,也就是每个对象的成员变量只能定义一次

在这里插入图片描述
在这里插入图片描述


  • 引用成员变量const成员变量自定义类型成员(没有默认构造函数的)必须在初始化列表位置进行初始化
class B
{
public:
	B(int b)
		:_b(b)
	{}

private:
	int _b;
};

class A
{
public:
	A(int a, int& i)
		:_a(a) // const成员变量
		,_reti(i)// 引用类型成员变量
		,_b(1)//  自定义类型成员
	{}

private:
	const int _a;
	int& _reti;

	B _b;
};

对于const成员变量,引用成员变量必须在定义时初始化赋值,自定义类型成员在定义时会调用对应的默认构造函数,如果没有默认构造函数就需要在定义时显示调用对应的构造函数,而初始化列表就是对象的成员变量定义的地方。


  • 构造函数赋初值和初始化列表初始化混用

在这里插入图片描述


  • 尽量使用初始化列表,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会优先使用初始化列表进行初始化

  • 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

下面程序的结果是?

class A
{
public:
	A(int a)
		:_a1(a)
		,_a2(_a1)
	{}

	void Print()
	{
		cout << "_a1 = " << _a1 << endl;
		cout << "_a2 = " << _a2 << endl;
	}

private:
	int _a2;
	int _a1;
};

int main()
{
	A a(1);
	a.Print();

	return 0;
}

在这里插入图片描述
这就是因为,成员变量初始化的顺序与成员声明的顺序有关,我们先声明了成员变量a2,在声明成员变量a1。那么在初始化成员列表中我们先执行_a2(_a1),此时_a1是随机值,所以打印结果中_a1是1,_a2是随机值。


注意:C++11支持给成员变量声明缺省值,这个缺省值是给初始化列表使用。

二、static成员

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

问题:实现一个类,计算程序中正在使用的类对象个数

class A
{
public:
	A()
	{
		_count++;
	}

	A(const A& a)
	{
		_count++;
	}

	~A()
	{
		_count--;
	}

	int get_count()
	{
		return _count;
	}
private:
	static int _count;
};

int A::_count = 0;

这里我们就需要使用static成员变量,在每次调用构造函数和拷贝构造函数时_count++,每次调用析构函数时_count–。


  • 静态成员为所有类对象共享,不属于某个具体的对象,存放在静态区

下面类A的大小是多少?

class A
{
private:
	static int i;
};

int main()
{
	cout << sizeof(A) << endl;

	return 0;
}

在这里插入图片描述
A类的大小为1,也就是空类。

  • 静态成员变量必须在类外定义,定义时不添加static关键词,类中只是声明
  • 类静态成员即可用 类名::静态成员 或者 对象.静态成员来访问

在这里插入图片描述

  • 静态成员函数没有隐藏的this指针,不能访问任何非静态成员

在这里插入图片描述

在这里插入图片描述

  • 静态成员也是类成员,受public,protected,private访问限定符的限制

在这里插入图片描述
在这里插入图片描述
如果想访问静态成员 i,可以实现Geti()等函数来访问
在这里插入图片描述

三、友元

友元分为友元函数和友元类

友元函数
例如我们要对日期类重载<<操作符时,会发现无法将operator<<重载为成员函数,因为隐含的this指针占据了operator<<函数的第一个参数位置。这样重载的<<操作符就无法正常使用。
在这里插入图片描述

在这里插入图片描述
当然我们可以 d << cout这样使用,但是不是有点怪?
这是我们就需要将operator<<重载成全局函数,但成为全局函数时就无法访问对象的成员变量,此时就需要友元类解决(使用GetYear / GetMonth / GetDay函数也可以解决)。

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

class Date
{
	friend ostream& operator<<(ostream& _cout, const Date& d);

public:
	Date(int year = 0, int month = 0, int day = 0)
		:_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;
}
int main()
{
	Date d(2023, 9, 16);
	cout << d;

	return 0;
}

在这里插入图片描述

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

友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员

  • 友元关系是单向的,不具备交换性
    如下:B是A的友元类,B类可以访问A类的成员变量,A类不能访问B类的成员变量
    在这里插入图片描述
    在这里插入图片描述

  • 友元关系不能传递

  • 友元关系不能继承

四、内部类

内部类:如果一个类定义在另一个类的内部,这个类就叫左内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。

在这里插入图片描述
如图:B是A的内部类

注意:内部类是外部类的友元类。内部类可以通过外部类的对象参数来访问外部类中的所以成员,但外部类不是内部类的友元

  • 内部类可以定义在外部类的public,protected,private中
  • 内部类可以直接访问外部类中的static成员,不需要外部类的对象. 和 类名::
class A
{
public:
	class B
	{
	public:
		void func(const A& a)
		{
			cout << i << endl;
			cout << a._a << endl;
		}
	};

	A()
	:_a(0)
	{}
private:
	static int i;
	int _a;
};

int A::i = 0;

int main()
{
	A::B b;
	b.func(A());
	return 0;
}

在这里插入图片描述

  • sizeof(外部类) = 外部类,和内部类没有任何关系
class A
{
public:
	class B
	{
	private:
		int _b;
	};

	A()
	:_a(0)
	{}
private:
	static int i;
	int _a;
};

上述类的大小是?
在这里插入图片描述


总结

以上就是我对于初始化列表,static成员,友元,内部类,匿名对象的知识总结。感谢支持!!!
在这里插入图片描述

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

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

相关文章

js实现websocket服务端和客户端

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

城市社交活动系统+附近交友资源类短视频APP源码

城市社交活动系统附近交友资源类短视频&#xff0c;注意只有安卓端源码&#xff01;

Python中Mock和Patch的区别

前言&#xff1a; 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 在测试并行开发&#xff08;TPD&#xff09;中&#xff0c;代码开发是第一位的。 尽管如此&#xff0c;我们还是要写出开发的测试&#xff0c…

【JavaSE笔记】数据类型与变量

一、前言 在Java这门“啰嗦”的编程语言中,我们必须弄清楚每种数据类型的性质和用途,才能让程序“说人话”。要成为Java高手&#xff0c;就必须与各种数据类型打成一片。 本文则将带你认识Java中常见的两位“角色”—数据类型与变量。 二、数据类型 在Java中数据类型主要分…

leetcode刷题(简单篇):9.回文数

9.回文数 题目描述&#xff1a;给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数。 例如&…

怒刷LeetCode的第2天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一&#xff1a;滑动窗口 方法二&#xff1a;双指针加哈希表 第二题 题目来源 题目内容 解决方法 方法一&#xff1a;二分查找 方法二&#xff1a;归并排序 方法三&#xff1a;分治法 第三题 题目来源 题目内容 解…

理解HTTPS/TLS/SSL(二)可视化TLS握手过程并解密加密数据

文章目录 WireShark抓包TLS握手过程Client HelloServer HelloEncryped Extenstions, Certificate, Certificate VerifyChange Ciper Spec, FinshedTLS 1.2和TLS 1.3的区别能不能在进一步&#xff1f; 解密WireShark中抓到的TLS包参考资料 上一篇文章已经在本地使用了生成自签名…

从字符串中删除指定字符

任务描述 编写一个函数实现功能&#xff1a;从字符串中删除指定的字符。同一字母的大、小写按不同字符处理。例如&#xff1a;程序执行时输入字符串&#xff1a;turbo c and Borland c&#xff0c;从键盘输入字符n&#xff0c;则输出后变为&#xff1a;turbo c ad Borlad c。如…

【openscreen 】FrameId

当前同步的最新版测试代码中用到了FrameId类 Frameid E:\chromium\src\media\cast\common\frame_id.h属于第三方库:openscreen E:\chromium\src\third_party\openscreen\src\cast\streaming\frame_id.h 为啥我感觉是int64的? 支持+ <<

【C#】FileInfo类 对文件进行操作

提示&#xff1a;使用FileInfo类时&#xff0c;要引用System.IO命名空间。 using System.IO; FileInfo类 生成文件删除文件移动文件复制文件获取文件名判断文件是否存在属性列表其它常用方法 生成文件 Create()&#xff1a;在指定路径上创建文件。 FileInfo myFile new FileIn…

我们一直谈论“写代码”,但你会“读代码”吗?

编程&#xff0c;又被称作“写代码”&#xff0c;“敲代码”。 这个说法有可能会带来一点点误解&#xff0c;让人觉得如何“写”是学习编程要解决的主要问题。但事实并非如此。尽管最终代码要在键盘上敲出来&#xff0c;但这个过程在开发中的实际时间占比可能要远远小于你的预…

算法通过村第七关-树(递归/二叉树遍历)青铜笔记|手撕递归

文章目录 前言1. 递归的特征2. 如何写出好的递归3. 怎么看懂递归的代码总结 前言 提示&#xff1a;我们生活在24小时不眠不休的社会里但是没有24小时不眠不休的身体有些东西必须舍弃 -- 马特海格 这一关&#xff0c;我看要谈论的是递归问题&#xff0c;说到它就牵扯到很多问题了…

QT基础教学(QT对象间的关系)

文章目录 前言一、QT间的父子关系二、聚合关系三、组合关系四、关联关系五、依赖关系总结 前言 本篇文章我们来讲解QT对象间的关系&#xff0c;理清楚QT对象间的关系是非常重要的&#xff0c;没有理清楚QT间的对象关系可能会导致内存的泄漏等各种问题的出现。 资料合集地微信…

HarmonyOS开发:那些开发中常见的问题汇总(一)

前言 本来这篇文章需要讲述静态共享包如何实现远程依赖和上传以及关于静态共享包私服的搭建&#xff0c;非常遗憾的告诉大家&#xff0c;由于组织管理申请迟迟未通过&#xff0c;和部分文档官方权限暂未开放&#xff0c;关于这方面的讲解需要延后了&#xff0c;大概需要等到202…

HeyFriday AI:智能AI写作工具

【产品介绍】​ 名称 HeyFriday AI 具体描述​ HeyFriday是一款智能AI写作工具&#xff0c;可以帮助用户快速生成博客、广告、创意故事等各种类型的文本内容&#xff0c;节省时间和金钱。​HeyFriday的团队由前谷歌NLP科学家&#xff08;ALBERT的第一作者&#xff…

VIRTIO-BLK代码分析(5)virtqueue通信

virtqueue用于VIRTIO驱动和VIRTIO设备进行通信。每个VIRTIO设备可能有一个或多个virtqueue&#xff0c;VIRTIO-BLK的virtqueue数目可以通过num_queues设置。 通过函数vring_create_virtqueue创建virtqueue&#xff0c;通过函数virtqueue_add_sgs添加数据。目前存在split virtqu…

【网络编程】UDP Socket编程

UDP Socket编程 一. DatagramSocket二. DatagramPacket三. InetSocketAddress四. 执行流程五. 代码示例: UDP 回显服务器 数据报套接字&#xff1a; 使用传输层 UDP 协议 UDP: 即 User Datagram Protocol&#xff08;用户数据报协议&#xff09;&#xff0c;传输层协议。 UDP…

Jmeter系列-定时器Timers的基本介绍(11)

简介 JMeter中的定时器&#xff08;Timer&#xff09;是一种重要的元件&#xff0c;用于模拟用户在不同时间间隔内发送请求的场景。通过使用定时器&#xff0c;可以模拟负载、并发和容量等不同情况下的请求发送频率。 使用定时器 可以在取样器下添加定时器&#xff0c;这样定…

机器学习第五课--广告点击率预测项目以及特征选择的介绍

这个项目的主要的目的是通过给定的广告信息和用户信息来预测一个广告被点击与否。 如果广告有很大概率被点击就展示广告&#xff0c;如果概率低&#xff0c;就不展示。 因为如果广告没有被点击&#xff0c;对双方&#xff08;广告主、平台&#xff09;来讲都没有好处。所以预测…