C++第十弹---类与对象(七)

  ✨个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】

目录

1、再谈构造函数

1.1、构造函数体赋值

1.2、初始化列表

1.3、explicit关键字

2、static成员

2.1、概念

2.2、特性

2.3、面试题

总结


1、再谈构造函数


1.1、构造函数体赋值


在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。
 

class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
int main()
{Date d(2022,1,1);//此处可以F9断点进行调试return 0;
}

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


1.2、初始化列表


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


【注意】
1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)。
2. 类中包含以下成员,必须放在初始化列表位置进行初始化

a、引用成员变量
b、const成员变量
c、自定义类型成员(且该类没有默认构造函数时)

如下代码为不初始化以上三种情况的结果。

class A
{
public:// 初始化列表是每个成员变量定义初始化的位置A(int a):_a(a){//赋值修改} 
private:// 声明int _a;
};
class Date
{
public:// 初始化列表是每个成员变量定义初始化的位置Date(int year, int month, int day):_year(year), _month(month), _day(day){//赋值修改} 
private:// 声明 int _year = 2022;//缺省值int _month;int _day;// 必须走初始化,否则编译不通过int& c;const int b;A a;
};
int main()
{Date d(2022, 1, 1);return 0;
}

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

class Date
{
public:// 初始化列表是每个成员变量定义初始化的位置Date(int year, int month, int day):_n(1),_month(2)//一定先初始化列表{// 赋值修改_year = year;_month = month;_day = day;}private:// 声明int _year = 1;  // 缺省值int _month = 1;int _day;const int _n;
};int main()
{// 对象实例化Date d1(2024, 1, 31);return 0;
}

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

 

class A
{
public:A(int a):_a1(a), _a2(_a1){}void Print() {cout << _a1 << " " << _a2 << endl;}
private://根据类声明顺序进行初始化 先初始化_a2 再初始化_a1int _a2;int _a1;
};
int main() {A aa(1);aa.Print();
} //A.输出1 1
//B.程序崩溃
//C.编译不通过
//D.输出1 随机值

1.3、explicit关键字


构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值
的构造函数,还具有类型转换的作用。

1、单个参数构造参数

class Date
{
public:// 1. 单参构造函数,没有使用explicit修饰,具有类型转换作用// explicit修饰构造函数,禁止类型转换---explicit去掉之后,代码可以通过编译explicit Date(int year):_year(year){}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2022);//不使用explicit修饰构造函数则不报错,使用explicit修饰则不能强转d1 = 2023;// 用一个整形变量给日期类型对象赋值// 实际编译器背后会用2023构造一个无名对象,最后用无名对象给d1对象进行赋值}

2、第一个参数无默认值其余有默认值的构造函数 

class Date
{
public:// 2. 虽然有多个参数,但是创建对象时后两个参数可以不传递,没有使用explicit修饰,具有类型转换作用// explicit修饰构造函数,禁止类型转换explicit Date(int year, int month = 1, int day = 1): _year(year), _month(month), _day(day){}*/Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2022);//不使用explicit修饰构造函数则不报错,使用explicit修饰则不能强转d1 = 2023;// 用一个整形变量给日期类型对象赋值// 实际编译器背后会用2023构造一个无名对象,最后用无名对象给d1对象进行赋值
}

总结:

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


2、static成员


2.1、概念


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


面试题:实现一个类,计算程序中创建出了多少个类对象。
先了解完static成员再进行讲解。

2.2、特性

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

6.成员变量:属于每个类对象,存储在对象里面。

静态成员变量:属于类,属于类的每个对象共享,存储在静态区,它的声明周期是全局的。

7.静态成员变量不能给缺省值。


【问题】
1. 静态成员函数可以调用非静态成员函数吗?

静态成员函数不能调用非静态成员函数,因为静态成员函数没有this指针。
2. 非静态成员函数可以调用类的静态成员函数吗?

非静态成员函数可以调用静态成员函数。

2.3、面试题

实现一个类,计算程序中创建出了多少个类对象。

根据我们前面学习的知识,创建类对象有两种方式,一个为直接构造一个对象,二为拷贝构造一个对象,因此我们调用了几次对应的构造函数和拷贝构造函数,则就创建了多少个类对象。

但是我们怎么控制这个变量呢?如果直接创建一个成员变量,出了类就会自动销毁,我们怎样才能解决除了类不自动销毁这个问题呢?

此处的解决办法是定义一个静态成员变量,在类外进行初始化,调用对应的函数则将静态变量++。

具体代码如下:

class A
{
public:A(){++n;}A(const A& aa){++n;}// static成员函数没有this指针static int GetN(){return n;}
private:// 不是属于某一个对象,属于所有对象,属于整个类// 声明static int n;//静态成员变量
};
int A::n = 0;// 定义并初始化
// 静态成员变量必须在类外定义
int main()
{A a1, a2;//创建类a1 a2A a3(a1);//拷贝构造类a3cout << A::GetN() << endl;//正常运行应该为3return 0;
}

总结


本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

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

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

相关文章

制作nuget包并上传到nuget.org

下面是一个详细的步骤指南&#xff0c;用于创建一个简单的 C# NuGet 包并将其发布到 NuGet.org。我们将创建一个简单的数学库作为示例。 步骤 1: 创建一个新的类库项目 首先&#xff0c;我们需要创建一个新的类库项目。这可以通过 Visual Studio 或者 .NET CLI 完成。 使用 …

[linux][调度] 内核抢占入门 —— 线程调度次数与 CONFIG_PREEMPTION

在工作中&#xff0c;如果你正在做开发的工作&#xff0c;正在在写代码&#xff0c;这个时候测试同事在测试过程中测出了问题&#xff0c;需要你来定位解决&#xff0c;那么你就应该先暂停写代码的工作&#xff0c;转而来定位解决测试的问题&#xff1b;如果你正在定位测试的问…

mysql事务及存储引擎

目录 什么是事务 事务的ACIP特性 事务之间的影响 mysql隔离级别 事务隔离级别的作用范围 事务控制语句 mysql存储引擎 什么是事务 事务是一种机制、一个操作序列&#xff0c;包含了一组数据库操作命令&#xff0c;并且把所有的命令作为一个整体一起向系统提交或撤销操作…

AI预测福彩3D第15弹【2024年3月21日预测--第3套算法重新开始计算第4次测试】

今天咱们继续对第3套算法进行第4次测试&#xff0c;第3套算法加入了012路的权重。废话不多说了&#xff0c;直接上结果吧~ 最终&#xff0c;经过研判分析&#xff0c;2024年3月21日福彩3D的七码预测结果如下&#xff1a; 百位&#xff1a;4 5 7 1 0 6 2 十位&#xff1a;3 1 5 …

QML 布局管理器之GridLayout 项目demo

一.气体控制效果图 二.界面布局代码实现 //DottedLline.qml 虚线绘制 import QtQuick 2.12 import QtQuick.Shapes 1.12Shape {id:canvaswidth: parent.widthheight: parent.heightShapePath{strokeStyle: ShapePath.DashLinestartX: 8startY: 10dashPattern: [1, 3]PathLine{…

在Linux搭建Emlog博客结合内网穿透实现公网访问本地个人网站

文章目录 前言1. 网站搭建1.1 Emolog网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总结 前言 博客作为使…

Flink入门知识点汇总(二)

具体内容请看b站尚硅谷课程&#xff01; 32_Flink运行时架构_提交流程_Yarn应用模式_哔哩哔哩_bilibili 窗口 Flink的窗口并不是静态准备好的&#xff0c;而是动态创建的。数据流到达时不会准备24个或者其他完整数量的桶&#xff0c;而是当下桶接满了&#xff0c;才临时又拿新…

web前端之小功能聚集、简单交互效果

MENU 纯CSS实现可编辑文字霓虹灯闪烁效果css之实现流水文字、闪烁、荧光、炫酷web前端之文本擦除效果与下划线结合css之下划线动画 纯CSS实现可编辑文字霓虹灯闪烁效果 效果图 html <h1 contenteditable"true">Hello World</h1>style * {margin: 0;pa…

C/C++在线参考手册的使用技巧

cppreference.com是一个在线的C/C参考手册&#xff0c;是C/C学习者最常用的网站。 网址&#xff1a;cppreference.com 1&#xff0e;搜索 不知道为什么这个网站总是不能正常搜索&#xff0c;实在是太不方便了。 有两个退而求其次的方法&#xff1a; (1)通过搜索引擎指定域名…

C++常用的区块代码

很多人在刷题时都遇到过不会的情况 这篇文章希望可以帮到你&#xff01; 1.输入n将这个数倒着输出来&#xff1a; while(n!0){tn%10;printf("%d",t);nn/10; }只要会这条代码&#xff0c;很多题目都可以直接秒杀。 如&#xff1a; 输入一个整数n,算出它各个位数的乘积…

程序员想要搞钱不迷茫,这篇文章你可得码好啦!!!

年已经过完了&#xff0c;现在大家都已经返工返校了吧&#xff01;咱又要投入到新一年的战斗了&#xff01;春色恼人不等闲&#xff0c;相信咱都有一个实实在在的愿望和期许&#xff1a;身体健康&#xff0c;财源广进&#xff01;新的一年我们还得继续努力&#xff0c;多多搞钱…

利用IP地址查防止电子招投标串标行为

随着信息技术的快速发展&#xff0c;电子招投标已成为政府和企业采购的主要方式。然而&#xff0c;电子招投标中的串标问题也愈发突出&#xff0c;给公平竞争和资源分配带来了隐患。为了防止串标行为&#xff0c;利用IP地址查已成为一种有效手段。 IP地址查询&#xff1a;IP数…

002_avoid_for_loop_in_Matlab避免使用for循环

避免使用for循环 在程序设计思想中&#xff0c;循环是一个很有力的工具。在循环中&#xff0c;计算机很轻松地重复执行相同的操作。循环是汇编之上的编程中最重要的概念之一。Matlab的循环有两个语言构造&#xff0c;一个是for循环&#xff0c;另一个是while循环。在Matlab中&…

罗德与施瓦茨联合广和通全面验证RedCap模组FG132系列先进性能

近日&#xff0c;罗德与施瓦茨联合广和通完成Redcap(Reduce Capability)功能和性能验证。本次测试使用R&SCMX500 OBT(One Box Tester)无线通信测试仪&#xff0c;主要验证广和通RedCap模组FG132系列射频性能以及IP层吞吐量&#xff0c;包括RedCap上下行吞吐量和射频指标如矢…

【计算机网络篇】数据链路层(2)封装成帧和透明传输

文章目录 &#x1f95a;封装成帧和透明传输&#x1f388;封装成帧&#x1f388;透明传输&#x1f5d2;️面向字节的物理链路使用字节填充的方法实现透明传输。&#x1f5d2;️面向比特的物理链路使用比特填充的方法实现透明传输。 &#x1f6f8;练习 &#x1f95a;封装成帧和透…

Linux systemd详解

1、概念 1.1 systemd systemd 是一个用于管理 Linux 系统启动过程和系统服务的系统和服务管理器。它被设计为取代传统的 System V init 系统&#xff0c;提供了更快的启动时间、并行启动服务、更好的日志记录和更强大的管理功能。 1.2 unit Unit 是 systemd 中所有配置文件…

基于ssm校园美食交流系统论文

目 录 摘 要 1 前 言 3 第1章 概述 4 1.1 研究背景 4 1.2 研究目的 4 1.3 研究内容 4 第二章 开发技术介绍 5 2.1Java技术 6 2.2 Mysql数据库 6 2.3 B/S结构 7 2.4 SSM框架 8 第三章 系统分析 9 3.1 可行性分析 9 3.1.1 技术可行性 9 3.1.2 经济可行性 10 3.1.3 操作可行性 10…

字符函数与字符串函数

目录 一.字符分类函数 二.字符转化函数 三.strlen函数 函数的介绍 strlen函数的模拟实现 1.计算器法 2.递归 三.指针-指针的方式 四.strcpy函数 函数介绍 strcmp的模拟实现 五.strcat函数 函数介绍 strcat的模拟实现 六.strcmp函数 函数介绍 返回值 strcm…

Mysql学习--深入探究索引和事务的重点要点与考点

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

自动驾驶---Motion Planning之轨迹Path优化

1 背景 在之前的几篇文章中,不管是通过构建SL图《自动驾驶---Motion Planning之Path Boundary》,ST图《自动驾驶---Motion Planning之Speed Boundary》,又或者是构建SLT图《自动驾驶---Motion Planning之构建SLT Driving Corridor》,最终我们都是为了得到boundary的信息。 …