当前位置: 首页 > news >正文

C++学习记录——칠 类和对象(4)

文章目录

  • 1、const成员
  • 2、取地址及const取地址操作符重载
  • 3、构造函数续集
    • 1、初始化列表
    • 2、explicit关键字
  • 4、static成员
  • 5、匿名对象
  • 6、友元
    • 1.友元函数
    • 2、友元类
  • 7、内部类


1、const成员

看一段代码

class A
{
public:void Print(){cout << _a << endl;}
private:int _a = 10;
};
int main()
{A aa;aa.Print();return 0;
}

如果const A aa,那么就报错了。aa传过去自己的地址是类型是const A* &aa, 而Print函数能接受的参数类型应当是A* this,所以权限放大了,我们只要在类里面加上const。this指针的类型无法改变,因为他是一个隐含参数,所以要在函数上加上const。

	void Print() const{cout << _a << endl;}

对于内部不改变成员变量的成员函数,最好const修饰。在上篇的日期类中,比较函数,Print等也可以加上const。

2、取地址及const取地址操作符重载

这个重载也是默认成员函数,它也会自动生成,如果需要访问到指定的内容,就需要手动写。

	const A aa;aa.Print();cout << &aa << endl;

手动写默认函数可以这样

	A* operator&(){return this;}const A* operator&() const{return this;}

但没必要,自动生成的就够了。但有一些特殊需求就得自己写。

3、构造函数续集

1、初始化列表

如果这样写类,

class A
{
public:int _a1;int _a2;const int _a3;
};int main()
{A aa;return 0;
}

程序就会报错,显示有未初始化的成员,就是_a3.为什么默认构造函数没有初始化它?系统虽然处理内置类型,但不处理const修饰的类型,所以const修饰的变量需要我们在定义处初始化,A aa是对类这个整体的定义,里面的成员会依据构造函数处理,而const修饰的成员变量要在外围单独初始化。当然类里面给const修饰的变量缺省值也可。

不过这样写不够好,C++把它也放到类里,也就是初始化列表,对特殊变量的初始化放在一起。即使main函数体里也有对特殊变量的初始化,也还是按照类里的去定义,因为初始化只有一次,再之后不会再初始化。

	A():_a3(2){_a1++;}

把对_a1的使用放在声明之前,也没问题,都在类里,编译器还是会按照_a1的初始化值去++。初始化列表用冒号开头,中间连接用逗号

class A
{
public:A():_a3(2), _a2(1){_a1++;}void Print(){cout << _a1 << endl;cout << _a3 << endl;cout << _a2 << endl;}
private:int _a1 = 1;int _a2 = 2;const int _a3;
};

打印的结果是2 2 1.这里的规则是

初始化列表是它所有成员变量定义的位置
不管是否显示在初始化列表,编译器的每个变量都会被初始化列表去初始化

初始化列表有对某个变量的初始化,那就按照它给的值去执行,如果没有,那就按照构造函数去执行。

C++规定const修饰的变量,引用类型的变量,用到其他类里的成员变量必须在初始化列表里初始化。用到其他类的成员变量,也可以说是没有构造函数的自定义类型成员,它会是这样存在的

class B
{
public:B():_b(0){cout << "B" << endl;cout << _b << endl;}
private:int _b;
};

把它放到A前面,然后在A里

private:int _a1 = 1;int _a2 = 2;const int _a3;B _b;

那在调用aa.Print()时就会打印出B。我们也可以在B类初始化时写全缺省,那么_b的值就会按照全缺省去实现,但如果不是全缺省,就无法调用构造函数。

	B(int _b):_b(0){cout << "B" << endl;}

那么就要在A里的初始化列表去初始化

	A():_a3(2), _a2(1), _b(0){_a1++;_a2--;}

因为在初始化列表的变量列表都可以去找初始化的办法,所以写代码的时候可以把所有初始化都放在初始化列表里。

在类里,初始化的顺序是按照声明的顺序去做的,所以这方面也要注意。

2、explicit关键字

现在看这一段代码

class A
{
public:A(int a):_a1(a){cout << "A(int)" << endl;}A(const A& aa):_a1(aa._a1){cout << "A(const)" << endl;}void Print() {cout << _a1 << " " << _a2 << endl;}
private:int _a1;
};int main() 
{A aa1(1);A aa2 = 1;return 0;
}

对于aa2来说,这是一个隐式类型转换,1去创建一个A类型的临时变量,然后这个变量再去拷贝构造aa2这个变量。类里已经有了拷贝构造函数,但是打印结果的时候却没有A(const),没有调用拷贝构造,是因为编译器把它变成了用1来做构造,相当于aa2(1),减少工作量。

加一行代码: const A& ret = 10。只有加上const,才没有错误。这时候就是一个类型转换,引用针对的就是生成的临时变量。

如果不想类型转换,那么就在函数前加上explicit,代码就不可以转换了。这个对于单参数构造函数是有用的。多参数构造函数就需要这样用。

	A(int a1, int a2):_a1(a1),_a2(a2){}private:int _a1;int _a2;
	A aa2(1, 1);A aa3 = { 1, 1 };const A& ret = { 1, 1 };

这样也会调用拷贝构造。

4、static成员

创建一个类,计算创建了多少个类对象。

我们可以用构造函数来计算。假设用一个全局变量来存储数值,这是不行的,会和库里的变量冲突,我们可以不展开命名空间using namespace std;用什么展开什么
using std::cout using std::endl。但是全局变量是难以控制的。C++为了解决这个问题,把这个变量放到了类里面,并且加上了static。

class A
{
public:A(int a = 0){++count;}A(const A& aa){++count;}static int count;//属于所有对象,属于整个类
};

但是不能在类里面初始化这个值,这个变量是共有的,应当在类外面初始化
int A::count = 0。在外部想要打印时可以这样

cout << A::count << endl;
cout << aa2.count << endl;
A* ptr = nullptr;
cout << ptr->count << endl;

不过如果count为私有变量,上面几个方式就不行。那么我就可以在类里面写个函数,外边调用这个函数即可。

假设没有创建对象,比如把创建的代码放在一个函数里,而不是在main函数里。

void func()
{A aa1;A aa2(aa1);A aa3 = 1;
}

还是用static,让类里计算数值的函数变成静态函数,这样的优势就是没有this指针,它是静态区的,在外面就可以用A::函数名来调用。

int main()
{    func();cout << A::GetCount() << endl;
}

静态函数里不能使用类里的非静态变量,因为没有this,无法调用这些变量。

静态函数服务于静态变量,其它的不得插手。

void func()
{A aa1;A aa2(aa1);A aa3 = 1;A aa4[10];
}

这个的调用次数就是13,因为aa4给数组里的10个元素都初始化了,也就是调用了10次。

5、匿名对象

创建类对象时,不能A aa(),这样,因为编译器不知道这是函数还是类,但可以这样写,A(),这是匿名对象。匿名对象的生命周期只在这一行,它没有名字,可以调用成员函数,可以把它当做正常的类对象使用,但仅仅在这一行,到了下一行它就没有了。

6、友元

1.友元函数

友元之前写过,分为友元类和友元函数,虽然可以突破封装,可以作为一个类外部的函数访问类的私有成员,在类里用friend关键字声明即可。但它破坏了封装,所以尽量少用

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

2、友元类

甲类是乙类的友元类,那么甲类就可以直接访问乙类的私有成员。但是乙类不能访问甲类。

7、内部类

内部类就是在类的里面再定义一个类。

class A
{
private:int a;
public:class B{private:int b;};
};int main()
{A aa;cout << sizeof(aa) << endl;return 0;
}

结果是4.调试起来后查看aa的内容,也只有一个a。这个内部类B和定义在全局的B并无二意,空间上是独立的,但它受A的类域限制,在外部只能指定访问,A::B,但如果内部类是私有的,也不能访问。

内部类B是A的友元,也就是B里面可以直接访问A的私有成员。

结束。

相关文章:

C++学习记录——칠 类和对象(4)

文章目录1、const成员2、取地址及const取地址操作符重载3、构造函数续集1、初始化列表2、explicit关键字4、static成员5、匿名对象6、友元1.友元函数2、友元类7、内部类1、const成员 看一段代码 class A { public:void Print(){cout << _a << endl;} private:int…...

Python-项目实战--飞机大战-碰撞检测(8)

目标了解碰撞检测方法碰撞实现1.了解碰撞检测方法pygame提供了两个非常方便的方法可以实现碰撞检测&#xff1a;pygame.sprite.groupcollide()两个精灵组中所有的精灵的碰撞检测groupcollide(group1, group2, dokill1, dokill2, collided None) -> Sprite_dict如果将dokill…...

T06 成绩排序

查找和排序 题目&#xff1a;输入任意&#xff08;用户&#xff0c;成绩&#xff09;序列&#xff0c;可以获得成绩从高到低或从低到高的排列,相同成绩 都按先录入排列在前的规则处理。 示例&#xff1a; jack 70 peter 96 Tom 70 smith 67 从高到低 成…...

【机器学习】Linear and Nonlinear Regression 线性/非线性回归讲解

文章目录一、回归问题概述二、误差项定义三、独立同分布的假设四、似然函数的作用五、参数求解六、梯度下降算法七、参数更新方法八、优化参数设置一、回归问题概述 回归&#xff1a;根据工资和年龄&#xff0c;预测额度为多少 其中&#xff0c;工资和年龄被称为特征&#xff0…...

PyQt5数据库开发1 4.1 SQL Server 2008 R2如何开启数据库的远程连接

文章目录 前言 步骤/方法 1 使用windows身份登录 2 启用混合登录模式 3 允许远程连接服务器 4 设置sa用户属性 5 配置服务器 6 重新登录 7 配置SSCM 8 确认防火墙设置 注意事项 前言 SQL Server 2008 R2如何开启数据库的远程连接 SQL Server 2008默认是不允许远程连…...

javassm高校学生评教系统的设计与实现idea msyql

伴随着社会以及科学技术的发展&#xff0c;互联网已经渗透在人们的身边&#xff0c;网络慢慢的变成了人们的生活必不可少的一部分&#xff0c;紧接着网络飞速的发展&#xff0c;管理系统这一名词已不陌生&#xff0c;越来越多的学校、公司等机构都会定制一款属于自己个性化的管…...

为什么神经网络做不了2次函数拟合,网上的都是骗人的吗?

环境&#xff1a;tensorflow2 kaggle 这几天突发奇想&#xff0c;用深度学习训练2次函数。先在网上找找相同的资料这方面资料太少了。大多数如下&#xff1a; 。 给我的感觉就是&#xff0c;用深度学习来做&#xff0c;真的很容易。 网上写出代码分析的比较少。但是也找到了…...

【Java】Help notes about JAVA

JAVA语言帮助笔记Java的安装与JDKJava命名规范JAVA的数据类型自动类型转换强制类型转换JAVA的运算符取余运算结果的符号逻辑运算的短路运算三元运算符运算符优先级JAVA的流程控制分支结构JAVA类Scanner类Java的安装与JDK JDK安装网站&#xff1a;https://www.oracle.com/java/…...

2023北京老博会,北京养老展,第十届中国国际老年产业博览会

2023第十届&#xff08;北京&#xff09;国际老年产业博览会&#xff0c;将于08月28-30日盛大举办&#xff1b; 2023北京老博会&#xff1a;2023第十届中国&#xff08;北京&#xff09;国际老年产业博览会The 2023 tenth China (Beijing) International Aged industry Expo&a…...

C++展开模板参数包、函数参数包-(lambda+折叠表达式)

开门见山 以下代码可展开模板参数包和展开函数参数包。 // lambda折叠表达式(需C17) #include <iostream> using namespace std;// 1.展开模板参数包 template<typename ...T> void Func1() {([]() {cout << typeid(T).name() << endl;}(), ...);// …...

【Spark分布式内存计算框架——Spark Core】7. RDD Checkpoint、外部数据源

第五章 RDD Checkpoint RDD 数据可以持久化&#xff0c;但是持久化/缓存可以把数据放在内存中&#xff0c;虽然是快速的&#xff0c;但是也是最不可靠的&#xff1b;也可以把数据放在磁盘上&#xff0c;也不是完全可靠的&#xff01;例如磁盘会损坏等。 Checkpoint的产生就是…...

Connext DDSQoS参考

1 QoS策略列表 ConnextDDS 6.1.1版中所有QoS策略的高级视图。 1. QoS策略描述...

【正则表达式】获取html代码文本内所有<script>标签内容

文章目录一. 背景二. 思路与过程1. 正则表达式中需要限定<script>开头与结尾2. 增加标签格式的限定3. 不限制<script>首尾的内部内容4. 中间的内容不能出现闭合的情况三. 结果与代码四. 正则辅助工具一. 背景 之前要对学生提交的html代码进行检查&#xff0c;在获…...

有 9 种springMVC常用注解高频使用,来了解下?

文章目录1、Controller2、RequestMapping2.1 RequestMapping注解有六个属性2.1.1 value2.1.2 method2.1.3 consumes2.1.4 produces2.1.5 params2.1.6 headers2.2 Request Mapping&#xff08;"/helloword/?/aa"&#xff09;的Ant路径&#xff0c;匹配符2.3 Request …...

【ES6】掌握Promise和利用Promise封装ajax

&#x1f4bb; 【ES6】掌握Promise和利用Promise封装ajax &#x1f3e0;专栏&#xff1a;JavaScript &#x1f440;个人主页&#xff1a;繁星学编程&#x1f341; &#x1f9d1;个人简介&#xff1a;一个不断提高自我的平凡人&#x1f680; &#x1f50a;分享方向&#xff1a;目…...

REDIS-持久化方案

我们知道redis是内存数据库&#xff0c;它的数据是存储在内存中的&#xff0c;我们知道内存的一个特点是断电数据就丢失&#xff0c;所以redis提供了持久化功能&#xff0c;可以将内存中的数据状态存储到磁盘里面&#xff0c;避免数据丢失。 Redis持久化有三种方案&#xff0c;…...

五、Java框架之Maven进阶

黑马课程 文章目录1. 分模块开发1.1 分模块开发入门案例示例&#xff1a;抽取domain层示例&#xff1a;抽取dao层1.2 依赖管理2. 聚合和继承2.1 聚合概述聚合实现步骤2.2 继承 dependencyManagement3. 属性管理3.1 依赖版本属性管理3.2 配置文件属性管理&#xff08;了解&#…...

1.前言【Java面试第三季】

1.前言【Java面试第三季】前言推荐1.前言00_前言闲聊和课程说明本课程介绍目前考核的变化趋势vcr集数和坚持学长谷粉面试题复盘反馈最后前言 2023-2-1 12:30:05 以下内容源自 【尚硅谷Java大厂面试题第3季&#xff0c;跳槽必刷题目必扫技术盲点&#xff08;周阳主讲&#xff0…...

06分支限界法

文章目录八数码难题普通BFS算法全局择优算法&#xff08;A算法&#xff0c;启发式搜索算法&#xff09;单源最短路径问题装载问题算法思想&#xff1a;队列式分支限界法优先队列式分支限界法布线问题最大团问题批处理作业调度问题分支限界法与回溯法的区别&#xff1a; &#x…...

Docker Compose编排

一、概念1、Docker Compose是什么Docker Compose的前身是Fig&#xff0c;它是一个定义及运行多个Docker容器的工具通过 Compose&#xff0c;不需要使用shell脚本来启动容器&#xff0c;而使用 YAML 文件来配置应用程序需要的所有服务然后使用一个命令&#xff0c;根据 YAML 的文…...

Docker进阶 - 11. Docker Compose 编排服务

注&#xff1a;本文只对一些重要步骤和yml文件进行一些讲解&#xff0c;其他的具体程序没有记录。 目录 1. 原始的微服务工程编排(不使用Compose) 2. 使用Compose编排微服务 2.1 编写 docker-compose.yml 文件 2.2 修改并构建微服务工程镜像 2.3 启动 docker-compose 服务…...

福利篇2——嵌入式岗位笔试面试资料汇总(含大厂笔试面试真题)

前言 汇总嵌入式软件岗位笔试面试资料,供参考。 文章目录 前言一、公司嵌入式面经1、小米1)面试时长2)面试问题2、科大讯飞1)面试时长2)面试题目3、其余公司面经二、嵌入式笔试面试资料(全)三、嵌入式岗位薪资报告四、硬件岗位薪资报告一、公司嵌入式面经 1、小米 1)…...

[ubuntu]LVM磁盘管理

LVM是 Logical Volume Manager&#xff08;逻辑卷管理&#xff09;的简写&#xff0c;是Linux环境下对磁盘分区进行管理的一种机制&#xff0c;由Heinz Mauelshagen在Linux 2.4内核上实现。LVM可以实现用户在无需停机的情况下动态调整各个分区大小。1.简介 ​ LVM本质上是一个…...

开源流程引擎Camunda

开源流程引擎Camunda 文章作者&#xff1a;智星 1.简介 Camunda是一个轻量级的商业流程开源平台&#xff0c;是一种基于Java的框架&#xff0c;持久层采用Mybatis&#xff0c;可以内嵌集成到Java应用、SpringBooot应用中&#xff0c;也可以独立运行&#xff0c;其支持BPMN&a…...

【PTA Advanced】1155 Heap Paths(C++)

目录 题目 Input Specification: Output Specification: Sample Input 1: Sample Output 1: Sample Input 2: Sample Output 2: Sample Input 3: Sample Output 3: 思路 代码 题目 In computer science, a heap is a specialized tree-based data structure that s…...

Educational Codeforces Round 129 (Rated for Div. 2)

A. Game with Cards. 题目链接 题目大意&#xff1a; Alice和Bob玩卡牌。Alice有n张&#xff0c;Bob有m张。第一轮选手出一张数字卡牌。第二轮另一个选手要选择一张比他大的&#xff0c;依此类推。谁没有牌可出则输。问Alice和Bob分别先手时&#xff0c;谁赢&#xff1f;输出…...

[数据库]表的增删改查

●&#x1f9d1;个人主页:你帅你先说. ●&#x1f4c3;欢迎点赞&#x1f44d;关注&#x1f4a1;收藏&#x1f496; ●&#x1f4d6;既选择了远方&#xff0c;便只顾风雨兼程。 ●&#x1f91f;欢迎大家有问题随时私信我&#xff01; ●&#x1f9d0;版权&#xff1a;本文由[你帅…...

分享77个JS菜单导航,总有一款适合您

分享77个JS菜单导航&#xff0c;总有一款适合您 77个JS菜单导航下载链接&#xff1a;https://pan.baidu.com/s/1e_384_1KC2oSTDy7AaD3og?pwdzkw6 提取码&#xff1a;zkw6 Python采集代码下载链接&#xff1a;https://wwgn.lanzoul.com/iKGwb0kye3wj class ChinaZJsSeleni…...

kubernetes -- 核心组件介绍以及组件的运行流程

常用组件大白话说 如果想要官方的&#xff0c;详细的信息&#xff0c;请看官方文档。 https://kubernetes.io/zh-cn/docs/concepts/overview/components/ 现在介绍一些核心的概念&#xff1a; etcd&#xff1a;存储所有节点的信息&#xff0c;节点上部署的容器信息等都存在数…...

微信小程序Springboot短视频分享系统

3.1小程序端 用户注册页面&#xff0c;输入用户的个人信息点击注册即可。 注册完成后会返回到登录页面&#xff0c;用户输入自己注册的账号密码即可登录成功 登录成功后我们可以看到有相关的视频还有视频信息&#xff0c;我的信息等。 视频信息推荐是按照点击次数进行推荐的&am…...

wordpress面包屑/seo发包技术教程

我们在产品原型设计时&#xff0c;经常需要制作高保真原型&#xff0c;在视觉效果及交互体验上尽量与最终产品相近&#xff0c;以便向别人展示或者供用户调研时使用。移动平台的交互方式非常丰富&#xff0c;下面就像大家介绍几种iPhone上常用的交互动作在Axure中的实现方式。我…...

网站二维码收费怎么做/自动引流推广app

在使用之前&#xff0c;首先要创建一个Ext.data.Store的实例&#xff0c;如下面的代码所示。 var data [ [boy, 0], [girl, 1] ]; var store new Ext.data.Store({ proxy: new Ext.data.MemoryProxy(data), reader: new Ext.data.ArrayReader(…...

阿里巴巴批发网站上面怎么做微商/网络营销建议

如何修改windows 2008&#xff08;R2&#xff09;的远程桌面连接数 前几天给32个核的工作站上装了个windows 2008 r2 很不错&#xff0c;好多人都想远程使用&#xff0c;但发现最多只能两个同时使用。 对2003比较熟悉 2008应该也差不多&#xff0c;在组策略里找呀找&#xff0c…...

什么叫网站建设/企业培训课程视频

我正在尝试使用Sipjs的帮助为用户设置Asterisk语音聊天&#xff0c;遵循SIPJS docs http://sipjs.com/guides/server-configuration/asterisk上给出的说明 . 用户已创建并已连接 . 他们可以通过Zoiper互相打电话 . 但无法通过Sipjs或SipML5调用 . 当任何人用户从Sipjs或SipMl5进…...

网站开发 方案 报价单/国内的搜索引擎排名

apply() 方法 apply方法是Scala提供的一个语法糖 类名括号&#xff0c;调用对象的apply方法 对象名括号&#xff0c;调用类的apply方法 对apply方法的简单测试&#xff1a;&#xff08;其中&#xff0c;带 new -- class ApplyTest&#xff0c;不带 new -- object ApplyTest&a…...

网站百度收录秒收方法/抖音网络营销案例分析

高并发架构 消息队列搜索引擎缓存分库分表读写分离设计高并发系统 高并发架构部分内容 缓存&#xff1a; Redis高可用&#xff1a; 高并发系统设计&#xff1a; 分布式系统 分布式业务系统&#xff0c;就是把原来用 Java 开发的一个大块系统&#xff0c;给拆分成多个子系统&a…...