类和对象(二)(C++)

初始化列表

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

虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式

 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. 类中包含以下成员,必须放在初始化列表位置进行初始化:

引用

const

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

初始化列表可以理解为每个对象定义的地方,所以上述三种类型都必须在初始化列表定义

类中的私有对象可以理解为声明

初始化列表写不写都会走,没有显式写,走默认构造和缺省值,没有的话报错

class Stack
{
public:Stack(int capacity=4){_capacity = capacity;_size = 0;_a = (int*)malloc(sizeof(int) * _capacity);if (_a == nullptr){perror("malloc fail");return;}}~Stack(){free(_a);_capacity = 0;_size = 0;}
private:int* _a;int _capacity;int _size;
};
class Myqueue
{
public:Myqueue(){}
private:Stack st1;Stack st2;int _size;
};

 这里加入stack没有默认构造,Myqueue也无法生成默认构造,这时候我们使用使用初始化列表

在成员变量中,有缺省值的话也是给初始化列表用的

初始化列表初始化顺序:

观察如下代码,打印结果是什么?

class A
{
public:A(int a):_a1(a), _a2(_a1){}void Print() {cout << _a1 << " " << _a2 << endl;}
private:int _a2;int _a1;
};

成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关 ,所以_a1是1,_a2是随机值

单参数构造函数:

class A
{
public:A(int a):_a(a){cout << "构造函数" << endl;}A(const A& aa):_a(aa._a)//{cout << "拷贝构造" << endl;}
private:int _a;int _a1;int _a2;
};
int main()
{A a1(2);A a2 = a1;return 0;
}

 

上面的写法会调用构造和拷贝构造,但如果我这样写A a2 = 2;,就直接调用构造,这是编译器做的优化,进行了隐式类型转换

但用引用接收的话要加const,const  A& a4 = 3;,因为3产生的临时变量具有常性

多参数构造函数:

多参数和单参数差不多,只是形式有点小变化

class A
{
public:A(int a, int b):_a(0),_a1(a),_a2(b){cout << " A(int a,int b)" << endl;}A(const A& aa):_a(aa._a)//{cout << "拷贝构造" << endl;}
private:int _a;int _a1;int _a2;
};
int main()
{
A aa1 = { 1, 2 };return 0;
}

这里隐式类型转换,参数加中括号 ,结果一样

explicit

用explicit修饰构造函数,将会禁止构造函数的隐式转换

class A
{
public://explicit A(int a, int b)//不支持直接转换explicit  A(int a, int b):_a(0),_a1(a),_a2(b){cout << " A(int a,int b)" << endl;}A(const A& aa):_a(aa._a)//{cout << "拷贝构造" << endl;}
private:int _a;int _a1;int _a2;
};
int main()
{A a1 = { 1,2 };return 0;
}

 static成员:

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

static变量不能在类中定义,只能声明,因为其存在静态区,不能给缺省值,否则要走初始化列表定义

class C
{
public:C() {++_scount; }C(const C& t){ ++_scount;}~C(){--_scount; }static int Get_Count() //静态成员函数{ return _scount; }
private://私有拿不到static int _scount;
};
int C::_scount = 0;

 上述代码是实现一个类,计算程序中创建出了多少个类对象

因为私有拿不到静态成员,所以这里这一个专门获取静态成员的函数,用static修饰,但静态成员函数没有隐藏的this指针,不能访问任何非静态成员

友元:

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

友元函数:

现在尝试去重载operator<<,然后发现没办法将operator<<重载成成员函数。因为cout的输出流对 象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作数了。但是实际使用 中cout需要是第一个形参对象,才能正常使用。所以要将operator<<重载成全局函数。但又会导致类外没办 法访问成员,此时就需要友元来解决,这个我们在日期类的实现中有提到过11

友元函数可访问类的私有和保护成员,但不是类的成员函数

友元函数的调用与普通函数的调用原理相同

友元类:

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

class Time
{// 声明 Date是Time的友元// Date中可以访问Time的私有// 但是Time中不能访问Date的私有friend class Date;
public:Time(int hour = 0, int minute = 0, int second = 0): _hour(hour), _minute(minute), _second(second){}
private:int _hour;int _minute;int _second;
};class Date
{
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){_t._hour++;}void SetTime(int hour, int minute, int second){// 直接访问时间类私有的成员变量_t._hour = hour;_t._minute = minute;_t._second = second;}
private:int _year;int _month;int _day;Time _t;
};

内部类:

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

class A
{
private:static int k;int h;
public:void func(){}
private:// 内部类// 独立的类,放到A里面// 仅仅受到类域限制class B // B天生就是A的友元{public:void foo(const A& a){cout << k << endl;cout << a.h << endl;}private:int _b;};
};

涉及构造函数,拷贝构造函数的优化:

#include <iostream>
using namespace std;
class A
{
public:A(int n=4):_a(n){cout <<"A()" << endl;}A(const A& aa):_a(aa._a){cout << "A(const A&aa)" << endl;}A& operator=(const A& aa){_a = aa._a;cout << "A& operator"<< endl;return *this;}~A(){cout << "~A()" << endl;}
private:int _a;
};
void f1(A aa)
{
}
//void f1( const A& aa)//加引用是因为临时变量具有常性
//{
//}
int main()
{A aa1;f1(aa1);cout << endl;f1(2);cout << endl;//连续的构造加拷贝构造优化为构造return 0;
}

 

传值传参时f1(2)只调用了构造函数,是因为连续的构造函数加拷贝构造会直接优化为构造,但引用传参的优化效果还不太明显

A f2()
{A aa;return aa;//拷贝构造加拷贝构造优化为一个拷贝构造
}
int main()
{A ret1 = f2();cout << endl;return 0;
}

 

这里建议用vs2019看优化程度,因为vs2022优化程度力度很大

这样写就成为了赋值加拷贝,所以不会进行优化,建议按上面写法来

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

elementui Menu 二级菜单 min-width修改无效

原因&#xff1a;可能是生成的二级菜单样式里面没有带特定的hash属性 而vue代码里面样式里带了 scoped生成的样式有改样式选择器 从而无法成功选择 解决&#xff1a;让样式可以全局选择 不带属性选择器 单文件组件 CSS 功能 | Vue.js :global(.el-menu--vertical .el-menu--p…

Flink端到端的精确一次(Exactly-Once)

目录 状态一致性 端到端的状态一致性 端到端精确一次&#xff08;End-To-End Exactly-Once&#xff09; Flink内部的Exactly-Once 输入端保证 输出端保证 幂等写入 事务写入 Flink和Kafka连接时的精确一次保证 整体介绍 需要的配置 案例 状态一致性 流式计算本身就…

探索智慧林业系统的总体架构与应用

背景&#xff1a; 随着人们对森林资源保护和管理的重视&#xff0c;智慧林业系统作为一种新兴的林业管理手段&#xff0c;正在逐渐受到广泛关注和应用。智慧林业系统的总体架构设计与应用&#xff0c;将现代信息技术与林业管理相结合&#xff0c;为森林资源的保护、管理和利用…

Unity3d简单对话系统的实现——使用Dialogue editor完成对话系统

目录 前言 使用方法 1.下载dialogue editor 2.新建空物体 3.对对话内容进行编辑 4.对话画布建立 5.触发对话框代码 结束语 前言 今天是坚持写博客的第21天&#xff0c;很高兴自己可以坚持&#xff0c;也希望能与大家一起进步。我们今天来看unity3d当中的一个可以轻松实…

Qt下调用Snap7库与西门子PLC通信

文章目录 前言一、Snap7源码下载二、Snap7的dll常用函数功能介绍三、Snap7Lib.pri模块的封装四、下载链接总结 前言 本文主要讲述了在Qt下调用Snap7库与西门子PLC进行通信&#xff0c;在这里将Snap7的源码与动态库整合在一起封装了一个自己的Snap7Lib.pri子模块&#xff0c;方…

RHEL - 订阅、注册系统和 Yum Repository(新版界面)

《OpenShift / RHEL / DevSecOps 汇总目录》 演示环境说明 本文需要有 redhat.com 账号以及包含 RHEL 的有效订阅。 演示环境使用了通过 minimal 方式安装的 RHEL 7.6 环境&#xff0c;RHEL 可以访问互联网。 红帽网站 access.redhat.com 针对新用户提供了新版界面&#xff0…

vue3+vite插件开发

插件开发目的:由于我司使用的前端技术栈为vue3tsvite2.Xaxios,在前端代码框架设计初期,做了把axios挂载到proxy对象上的操作,具体可见我的另一篇文章vue3TS自动化封装全局api_ts 封装腾讯位置api-CSDN博客 现在可以实现vue2的类似this.$api.xxx去调用接口,但是vue2源码使用的是…

【CS.AI】GPT-4o:重新定义人工智能的新标杆

文章目录 1 序言2 GPT-4o的技术亮点3 GPT-4o与前代版本的对比3.1 热门AI模型对比表格GPT-3.5GPT-4GPT-4oBERTT5 3.2 其他 4 个人体验与感受5 结论 1 序言 嘿&#xff0c;大家好&#xff01;今天要聊聊一个超级酷的AI新突破——GPT-4o&#xff01;最近&#xff0c;OpenAI发布了…

MTK联发科MT6897(天玑8300)5G智能移动处理器规格参数

天玑 8300 采用台积电第二代 4nm 制程&#xff0c;基于 Armv9 CPU 架构&#xff0c;八核 CPU 包含 4 个 Cortex-A715 性能核心和 4 个 Cortex-A510 能效核心&#xff0c;CPU 峰值性能较上一代提升 20%&#xff0c;功耗节省 30%。 此外&#xff0c;天玑 8300 搭载 6 核 GPU Mal…

kafka-重试和死信主题(SpringBoot整合Kafka)

文章目录 1、重试和死信主题2、死信队列3、代码演示3.1、appication.yml3.2、引入spring-kafka依赖3.3、创建SpringBoot启动类3.4、创建生产者发送消息3.5、创建消费者消费消息 1、重试和死信主题 kafka默认支持重试和死信主题 重试主题&#xff1a;当消费者消费消息异常时&…

android中调用onnxruntime框架

创建空白项目 安装Android Studio及创建空白项目参考&#xff1a;【安卓Java原生开发学习记录】一、安卓开发环境的搭建与HelloWorld&#xff08;详细图文解释&#xff09;_安卓原生开发-CSDN博客 切记&#xff1a;build configuration language 一定选择Groovy&#xff01;官…

Java——IO流(一)-(1/8):File、IO流概述、File文件对象的创建(介绍、实例演示)

目录 File IO流概述 File文件对象的创建 介绍 实例演示 File 存储数据的方案 变量 double money 9999.5 数组 int[] age new int[100];对象 Student s new Student()集合 List<Student> students new ArrayList<>()…

Chrome 源码阅读:跟踪一个鼠标事件的流程

我们通过在关键节点打断点的方式&#xff0c;去分析一个鼠标事件的流程。 我们知道chromium是多进程模型&#xff0c;那么&#xff0c;我们可以推测&#xff1a;一个鼠标消息先从主进程产生&#xff0c;再通过跨进程通信发送给渲染进程&#xff0c;渲染进程再发送给WebFrame&a…

L45---506.相对名次(java)--排序

1.题目描述 2.知识点 &#xff08;1&#xff09;String.join(" ", words) 是 Java 中的一个语法&#xff0c;用于将数组或集合中的元素连接成一个单独的字符串&#xff0c;连接时使用指定的分隔符。这里的 " " 是作为分隔符使用的一个空格字符串。 Strin…

4、后端本地环境搭建

后端本地环境搭建 4.1 安装jdk 下载完成后双击安装的 jdk &#xff0c;点下一步&#xff0c;选择安装目录&#xff0c;一直点下一步&#xff0c;直到结束。 安装完成后同样需要配置环境变量 window s 搜索查看高级系统设置—— 高级 —— 环境变量 —— 系统变量 1、新建一…

API接口测试工具:jmeter的安装、汉化、Jmeter桌面快捷图标和基本使用

文章目录 测试工具&#xff1a;JmeterJmeter安装和配置Jmeter汉化设置中文语言&#xff1a;永久方式设置中文语言&#xff1a;临时方式 设置Jmeter桌面快捷图标jmeter基本用法Jmeter无法保存测试问题解决 测试工具&#xff1a;Jmeter Jmeter依赖于JDK&#xff0c;所以必须确保…

第十一届蓝桥杯C++青少年组中/高级组国赛2020年10月真题解析

一、单选题 第1题 在数组中&#xff0c;数组名表示&#xff08; &#xff09;. A:数组第1个元素的首地址 B:数组第2个元素的首地址 C:数组所有元素的首地址&#xff0c; D:数组最后1个元素的首地址 答案&#xff1a;A 数组名是一个地址&#xff0c;指向第一个元素 第2题 …

中继器、集线器、网桥、交换机、路由器和网关

目录 前言一、中继器、集线器1.1 中继器1.2 集线器 二、网桥、交换机2.1 网桥2.1.1 认识网桥2.1.2 网桥的工作原理2.1.3 生成树网桥 2.2 交换机2.2.1 交换机的特征2.2.2 交换机的交换模式2.2.3 交换机的功能 三、路由器、网关3.1 路由器的介绍3.2 路由器的工作过程3.2.1 前置知…

多客圈子论坛系统 httpGet 任意文件读取漏洞复现

0x01 产品简介 多客圈子论坛系统是一种面向特定人群或特定话题的社交网络&#xff0c;它提供了用户之间交流、分享、讨论的平台。在这个系统中&#xff0c;用户可以创建、加入不同的圈子&#xff0c;圈子可以是基于兴趣、地域、职业等不同主题的。用户可以在圈子中发帖、评论、…

17- Redis 中的 quicklist 数据结构

在 Redis 3.0 之前&#xff0c;List 对象的底层数据结构是双向链表或者压缩列表&#xff0c;然后在 Redis 3.2 的时候&#xff0c;List 对象的底层改由 quicklist 数据结构实现。 其实 quicklist 就是【双向链表 压缩列表】组合&#xff0c;因为一个 quicklist 就是一个链表&…