C++初阶 | [四] 类和对象(下)

摘要:初始化列表,explicit关键字,匿名对象,static成员,友元,内部类,编译器优化

类是对某一类实体(对象)来进行描述的,描述该对象具有哪些属性、哪些方法,描述完成后就形成了一种新的自定义类型,才用该自定义类型就可以实例化具体的对象。


1. 初始化列表

构造函数函数体内是对成员变量进行赋值,而不是初始化!

初始化列表:成员变量定义的地方

为什么规定初始化列表是所有成员变量定义的地方?

对于以下三类特殊的成员变量类型,初始化列表的存在是必要的:

  • const 成员变量—— const 变量必须在定义时初始化
  • 引用 —— 引用必须初始化
  • 自己没有默认构造函数自定义类型变量

warning:Initialization is not assignment. Initialization happens when a variable is given a value when it is created. Assignement obliterates an object's current value and replaces that value with a new one.

 Four different ways  to define an int variable named units_sold and initialize it to 0:

  • int units_sold = 0;
  • int units_sold = {0}; //list initialization (C++11)
  • int units_solc{ 0 }; //list initialization (C++11)
  • int units_sold(0);

——《C++ Primer》

Use

  1. 冒号开始,逗号分隔,初始化值/表达式 用括号括起来。示例如下。
  2. 成员变量走初始化列表的顺序为成员变量声明的顺序.(如下图,先用v2初始化v1,而v2还未初始化所存储的为随机值)
  3. C++规定初始化列表是每个成员变量定义的地方,每个成员变量会走初始化列表(所以成员变量的初始化尽量使用初始化列表),定义的时候不给初始值——即在初始化列表没有显式写的成员变量——未被初始化。
  4. 在初始化列表没写的成员变量,对于内置类型将不做处理——初始化值为随机值(但因编译器不同而异),对于自定义类型默认调用它自己的构造函数

sum.能用初始化列表就用初始化列表,但同时有些场景需要初始化列表和构造函数体混用。(根据具体的需求而异)

补充:C++11 支持在成员变量声明的时候给缺省值,这个缺省值是给初始化列表用的,如果初始化列表没有显式给初始值,就用缺省值作为初始化值。


2. explicit 关键字

  • C++98 支持单参数隐式类型转化

  • C++11 进一步支持多参数隐式类型转化

 在构造函数前加 explicit 使得不能进行隐式类型转换:(示例如下)

class B
{
public:
	explicit B(const int b1, const int b2)
	{
		_b1 = b1;
		_b2 = b2;
	}
	explicit B(const B& b)
	{
		_b1 = b._b1;
		_b2 = b._b2;
	}
private:
	int _b1;
	int _b2;
};

3. 匿名对象

  • 匿名对象:生命周期仅在改匿名对象定义的这一行。e.g.A(7);
  • 有名对象:生命周期在该作用域。e.g.A aa(7);

用途:

  1. 传参(如果单/多参数隐式类型转化被禁)
  2. 定义对象就是为了调用成员函数 → 就可以用匿名对象去调用
  3. ……(匿名对象的用途是十分广泛的)

const引用会延长匿名对象的生命周期

const引用其实使得匿名对象变成了有名对象:引用给了匿名对象别名,这个“别名”的生命周期即为被引用的匿名对象的生命周期。e.g.const A& ref = A();


4. static 成员

如果我们有如下两个需求:

  • 统计累计创建了多少个对象
  • 统计正在使用的对象还有多少个

统计累计创建的对象:首先,我们可以选择创建全局变量来统计。同时,因为创建对象会自动调用构造函数,所以我们在构造函数体内对这个用于统计的变量进行++操作,这样每次创建一个对象,就会调用并执行构造函数,每次执行都会累计对这个全局变量++。

统计正在使用的对象:对象销毁会自动调用析构函数,创建的对象 - 已经析构的对象 = 正在使用的对象。

int e = 0;//统计累计创建的对象
int now_e = 0;//统计仍在使用的对象

class A
{
public:
	A(const int a = 0)
	{
		++e;
		++now_e;
		_a = a;
	}
	~A()
	{
		--now_e;
	}
private:
	int _a;
};

问题:不够封装,全局变量可能会被随意修改,将造成需求之外的影响。 → “封装” → 将变量放入类中  →  私有变量无法访问 → static 成员

static 成员变量

static 成员变量的性质:

  1. 属于所有对象——即整个类,而不是某一个对象。
  2. 不能给缺省值。
  3. 不走初始化列表,初始化列表是某个对象的初始化,而 static 成员变量不属于某个对象。
  4. 位于静态区。

static 成员变量的声明与定义:类内声明,类外定义(静态成员变量一定要在类外进行初始化)

class A
{
private:
	static int m;//static成员变量声明
};//这样写A相当于空类

int A::m = 0;//static成员变量定义

访问 static 成员变量的两种情况下的方式:

  • 如果 static 成员变量是 public 的:①创建对象访问;②通过指针访问(这里的指针只是为了突破类域,而不会解引用,之前在类和对象上的this指针关于空指针的内容有详细解释);③直接访问。
    class A
    {
    public:
    	static int m;//static成员变量声明
    };//这样写A相当于空类
    
    int A::m = 0;//static成员变量定义
    
    int main()
    {
    	A aa;
    	aa.m;//①创建对象访问;
    
    	A* p = nullptr;
    	p->m;//②通过指针访问
    
    	A::m = 1;//③直接访问
    	return 0;
    }
    
  • 如果 static 成员变量是 非public 的:提供函数接口访问,这样可以使得 static 成员变量是只读不可修改的(引用返回可修改,这个根据需求自己控制),不同于public的情况。
    class A
    {
    public:
    	int GetM()
    	{
    		return m;
    	}
    private:
    	static int m;//static成员变量声明
    };
    
    int A::m = 0;//static成员变量定义
    
    int main()
    {
    	A aa;
    	cout << aa.GetM() << endl;
    	return 0;
    }

static 成员函数

static 成员函数的性质:

  1. 没有 this 指针,不能访问非静态成员变量
  2. 访问方式同 static 成员变量——突破类域即可访问 

5. 友元

  • 友元函数

特性:

  1. 可以访问类的 private 和protected 的成员,但友元函数不是类的成员函数。
  2. 不能用 const 修饰(因为不是成员函数更没有 this 指针,const 修饰的是 this 指针)。
  3. 可在类定义的任何地方声明,不受访问限定符限制。
  4. 一个函数可以是多个类的友元函数。
  5. 友元函数的调用同普通函数
class Date
{
	
friend ostream& operator<<(ostream& out, Date d);//友元函数声明

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


ostream& operator<<(ostream& out, Date d)//函数定义
{
	out << d._year << "/" << d._month << "/" << d._day << endl;
	return out;
}

  • 友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。(如下代码,B类在A类友元声明之后,B类中的所有成员函数相当于在A类中都进行了友元声明——可以访问A类的非公有成员。注意:A类不可以访问B类的非公有成员。)

友元类的性质:

①单向性(如下,B可以访问A,但A不可以访问B);

②友元关系不传递(B是A的友元,A是C的友元,不能得出B是C的友元);

③不继承。

class A
{
	friend class B;

private:
	int _a;
};



class B
{
	void Print(A _aa)
	{
		cout<<_aa._a;
	}

	//A aa;//注意:这个只是声明,不开空间
};

6. 内部类

内部类:在类中再定义一个类。内部类受外部类的类域和访问限定符限制,此外内部类与外部类是两个独立的类。

使用场景:内部类可以应用于当你想定义一个类而仅在某个类中使用时。

注意:如上图,C不可以访问D的非公有成员, D在C类域之内又封装了一层,并且根据友元类的单向性也是如此。


7. 拷贝对象时编译器的一些优化

此部分内容仅作了解,在之前旧版本的博客有较为详细的讲述,详细内容可参见本文:C++ -4- 类和对象(下)


END

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

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

相关文章

【zabbix监控三】zabbix之部署代理服务器

一、部署代理服务器 分布式监控的作用&#xff1a; 分担server的几种压力解决多机房之间的网络延时问题 1、搭建proxy主机 1.1 关闭防火墙&#xff0c;修改主机名 systemctl disbale --now firewalld setenforce 0 hostnamectl set-hostname zbx-proxy su1.2 设置zabbix下…

【C++ Primer Plus学习记录】for循环

很多情况下都需要程序执行重复的任务&#xff0c;C中的for循环可以轻松地完成这种任务。 我们来从程序清单5.1了解for循环所做的工作&#xff0c;然后讨论它是如何工作的。 //forloop.cpp #if 1 #include<iostream> using namespace std;int main() {int i;for (i 0; …

百云齐鲁 | 云轴科技ZStack成功实践精选(山东)

山东省作为我国重要的工业基地和北方地区经济发展的战略支点&#xff0c;在“十四五”规划中将数字强省建设分为数字基础设施、数字科技、数字经济、数字政府、数字社会、数字生态六大部分&#xff0c;涵盖政治、经济、民生等多个方面&#xff0c;并将大数据、云计算、人工智能…

数电实验-----实现74LS153芯片扩展为8选1数据选择器以及应用(Quartus II )

目录 一、74LS153芯片介绍 管脚图 功能表 二、4选1选择器扩展为8选1选择器 1.扩展原理 2.电路图连接&#xff08;Quartus II &#xff09; 3.仿真结果 三、8选1选择器的应用 1.三变量表决器 2.奇偶校验电路 一、74LS153芯片介绍 74ls153芯片是属于四选一选择器的芯片。…

Nginx-负载均衡-动静分离-虚拟主机

负载均衡 负载均衡基本使用 1 配置上游服务器 upstream myserver { #是server外层server ip1:8080;server ip1:8080; }2 配置代理 server {location / { proxy_pass http://myserver;#请求转向myserver 定义的服务器列表 注意这个http不能丢 pro…

VulnHub DC-7

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

【数据结构与算法】Kadane‘s算法(动态规划、最大子数组和)

文章目录 一、算法原理二、例题2.1 最大子数组和2.2 环形子数组的最大和 一、算法原理 Kadanes算法是一种用于解决最大子数组和问题的动态规划算法。这类问题的目标是在给定整数数组中找到一个连续的子数组&#xff0c;使其元素之和最大&#xff08;数组含有负数&#xff09;。…

MySQL为什么选择了B+树

首先MySQL的数据**&#xff08;索引记录&#xff09;**是存在磁盘里的&#xff0c;磁盘读取非常慢&#xff0c;所以要尽可能减少磁盘操作&#xff0c;因此我们需要更好的利用索引。 首先索引按顺序排列了数据&#xff0c;那么很显然最好的查找方式是二分查找&#xff0c;数组自…

【Spring Boot】使用WebSocket协议完成来单提醒及客户催单功能

1 WebSocket介绍 WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信(双向传输)——浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c; 并进行双向数据传输。 1.1 HTTP协议和WebSocket协议对比 1、HTTP是短…

【10套模拟】【7】

关键字&#xff1a; 二叉排序树插入一定是叶子、单链表简单选择排序、子串匹配、层次遍历

【Python】问题描述:输入A、B,输出A+B。样例输入12 45样例输出57

1、问题描述 输入A、B&#xff0c;输出AB。 样例输入 12 45 样例输出 57 nums list(map(int,input().split(" "))) print(sum(nums))

Java 算法篇-链表的经典算法:判断回文链表、判断环链表与寻找环入口节点(“龟兔赛跑“算法实现)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 链表的创建 2.0 判断回文链表说明 2.1 快慢指针方法 2.2 使用递归方式实现反转链表方法 2.3 实现判断回文链表 - 使用快慢指针与反转链表方法 3.0 判断环链表说明…

基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码

基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于人工水母优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

vue-admin-template改变接口地址

修改登录接口 1.f12查看请求接口 模仿返回数据写接口 修改方式1 1.在env.devolopment修改 修改方式2 vue.config.js 改成本地接口地址 配置转发 后端创建相应接口&#xff0c;使用map返回相同的数据 修改前端请求路径 修改前端返回状态码 utils里面的request.js

Iceberg学习笔记(1)—— 基础知识

Iceberg是一个面向海量数据分析场景的开放表格式&#xff08;Table Format&#xff09;&#xff0c;其设计的目的是解决数据存储和计算引擎之间的适配的问题 表格式&#xff08;Table Format&#xff09;可以理解为元数据以及数据文件的一种组织方式&#xff0c;处于计算框架&…

Positive Technologies 利用 PT Cloud Application Firewall 保护中小型企业的网络资源

云产品按月订购&#xff0c;无需购买硬件资源 PT Cloud Application Firewall 是 Positive Technologies 推出的首个用于保护网络应用程序的商用云产品。Web 应用层防火墙 (web application firewall, WAF) 现在可以通过 技术合作伙伴——授权服务商和云提供商以订购方式提供1…

浅析ChatGPT中涉及到的几种技术点

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

PHPmail 发送邮件错误 550 的原因是什么?

电子邮件错误消息链接到简单邮件传输协议 (SMTP)&#xff0c;这是一组发送和接收电子邮件的标准化规则。因此&#xff0c;它也称为 SMTP 550 错误代码。在某些情况下&#xff0c;电子邮件错误 550 是由收件人一方的问题引起的。 以下是电子邮件错误 550 的一些可能原因&#x…

华为数通HCIP 821BGP 知识点整理

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢AI编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;落798. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;️…

苹果(Apple)公司的新产品开发流程(一)

目录 简介 ANPP CSDN学院推荐 作者简介 简介 苹果这家企业给人的长期印象就是颠覆和创新。 而流程跟创新似乎是完全不搭边的两个平行线&#xff1a; 流程是一个做事的标准&#xff0c;定义了权力的边界&#xff0c;对应人员按章办事&#xff1b;而创新的主旋律是发散&am…