C++:类与对象(下)

前言:

前言:

上一篇博客我们介绍了类与对象中的几类默认成员函数,这篇让我们继续来学习类与对象吧!

个人主页:Pianeers

文章专栏:C++

如果有问题,欢迎评论区讨论!

希望能帮到大家,求点赞,关注加收藏!

目录

一、初始化列表

二、类型转换 

 三、static

 四、友元

五、内部类

 六、匿名对象

 七、拷贝对象时优化


一、初始化列表

我们之前的默认构造函数是用来初始化的,可以在函数内给成员变量初始化,但如果有一些特殊的成员呢?如:const成员变量,没有默认构造的类类型变量。

这时就要从之前说起,成员变量在private中只是声明并没有被定义,当创建一个对象时,成员变量需要被定义,这时要介绍初始化列表。

之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅式,就是初始化列表,所以初始化列表不仅可以定义还可以初始化

所以成员变量都要初始化列表中定义,初始化没有太多限制,但是有一些必须要在初始化列表中初始化。

①const成员变量

② 没有默认构造的类类型变量

③引⽤成员变量

它们都是被要求在定义的同时就要进行初始化的。

 

初始化列表的特点:

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

 ②每个成员变量在初始化列表中只能出现⼀次,因为语法理解上初始化列表认为是每个成员变量定义初始化的地⽅。

③成员变量的初始化与在类中的声明顺序有关,与在初始化列表中的顺序无关。

 以下还有几个需要注意的点:

①C++11⽀持在成员变量声明的位置给缺省值,这个缺省值主要是给没有显⽰在初始化列表初始化的成员使⽤的。

其中该缺省值的作用是:如果初始化列表没有显⽰初始化,默认就会⽤这个缺省值初始化。

class Time
{
public:Time(int hour):_hour(hour){cout << "Time()" << endl;}
private:int _hour;
};
class Date
{
public:void Print() const{cout << _year << "-" << _month << "-" << _day << endl;}
private:// 注意这⾥不是初始化,这⾥给的是缺省值,这个缺省值是给初始化列表的
// 如果初始化列表没有显⽰初始化,默认就会⽤这个缺省值初始化int _year=2024;int _month=7;int _day=16;Time _t=1;const int a=1;int* tmp = (int*)malloc(12);
};
int main()
{int i = 0;Date d1;d1.Print();return 0;
}

我个人建议能使用初始化列表初始化就用初始化列表,因为每个成员变量都要在初始化列表中定义 。

初始化列表中情况分析:

1.在初始化列表中初始化的成员。(显示写出来的)

2.没在初始化列表中初始化的成员。(没有写出的)

→→在声明时有缺省值时,用缺省值进行初始化。

→→②没有缺省值。

{

→→→①内置类型,大概率随机值,看编译器。

→→→②自定义类型,调用默认构造,没有则报错。

}

二、类型转换 

C++⽀持内置类型隐式类型转换为类类型对象,需要有相关内置类型为参数的构造函数。

如下:

当1这个类型直接拷贝构造给a时,1构造⼀个A的临时对象,再⽤这个临时对象拷⻉构造a。

当你不希望这种隐式类型转换发生,可以构造函数前⾯加explicit就不再⽀持隐式类型转换

class A
{
public:A(int a):_a1(a){}void print(){cout << _a1 << _a2 << endl;}
private:int _a1= 1;int _a2 = 2;
};
int main()
{A a = 1;a.print();return 0;
}

 三、static

在之前的C语言的学习中,我们了解了static关键字的作用是在程序中标记变量、方法或代码块为静态,同样的它在类中同样可以标记成员变量为静态

static的特点:

①⽤static修饰的成员变量,称之为静态成员变量,静态成员变量⼀定要在类外进⾏初始化

②⽤static修饰的成员函数,称之为静态成员函数,静态成员函数没有this指针,所以静态成员函数中可以访问其他的静态成员,但是不能访问⾮静态的,因为没有this指针。

③⾮静态的成员函数,可以访问任意的静态成员变量和静态成员函数。

静态成员也是类的成员public、protected、private 访问限定符的限制。可以通过类名::静态成员 或者 对象.静态成员访问任意的静态成员变量和静态成员函数。

静态成员变量为所有类对象所共享,不属于某个具体的对象,不存在对象中,存放在静态区;静态成员变量不能在声明位置给缺省值初始化,因为缺省值是个构造函数初始化列表的,静态成员变量不属于某个对象,不⾛构造函数初始化列表。

class B
{
public:B(){++a;}B(const B& c){++a;cout << "kaobe" << endl;}int rmid(){//⾮静态的成员函数,可以访问任意的静态成员变量和静态成员函数mid();return a;}static int mid(){//只能访问静态的return a;}
private://类里面声明static int a;int g = 0;
};
//类外面初始化
//突破类域就可以访问静态成员
int B::a=0;
int main()
{B b;cout << b.mid() << endl;B d(b);cout << d.mid() << endl;
}

 四、友元

当我们创建一个函数不在类以内时,因为成员变量被private修饰,所以成员变量不可以在函数内被访问,这时我们可以通过友元的方式,友元提供了⼀种突破类访问限定符封装的⽅式。

友元是一种很有效的方式,但是并不推荐使用,因为它会破坏封装

友元的特点:

①友元分为:友元函数和友元类,在函数声明或者类 声明的前⾯加friend,并且把友元声明放到⼀个类的⾥⾯。

②外部友元函数可访问类的私有和保护成员,友元函数仅仅是⼀种声明,他不是类的成员函数。

③友元函数可以在类定义的任何地⽅声明,不受类访问限定符限制。

④⼀个函数可以是多个类的友元函数。

⑤友元类的关系是单向的,不具有交换性,⽐如A类是B类的友元,但是B类不是A类的友元。

⑥友元类关系不能传递,如果A是B的友元, B是C的友元,但是A不是C的友元。

class B;
class A
{friend void func(const A& aaa,const B& bbb);
private:int a1;int a2;
};
class B
{friend void func(const A& aaa, const B& bbb);
private:int b1;int b2;
};
void func(const A&aaa,const B&bbb)
{cout << aaa.a1 << aaa.a2 << endl;cout << bbb.b1 << bbb.b2 << endl;
}
int main()
{A aa;B bb;func(aa, bb);
}

五、内部类

如果⼀个类定义在另⼀个类的内部,这个内部类就叫做内部类。

内部类的特点:
①内部类是⼀个独⽴的类,跟定义在全局相⽐,他只是受外部类类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类,sizeof(外部类)=外部类。

内部类默认是外部类的友元类。但内部类可以直接访问外部类中的static成员

③内部类可以定义在外部类的public、protected、private都是可以的 

class A
{
private:static int _k;int _h = 1;
public:class B // B默认就是A的友元{public:void foo(const A & a){cout << _k << endl; //OKcout << a._h << endl; //OK}};
};
int A::_k = 1;
int main()
{cout << sizeof(A) << endl;A::B b;A aa;b.foo(aa);return 0;
}

 六、匿名对象

⽤ 类型(实参) 定义出来的对象叫做匿名对象,相⽐之前我们定义的 类型 对象名(实参) 定义出来的 叫有名对象;匿名对象⽣命周期只在当前⼀⾏,⼀般临时定义⼀个对象当前⽤⼀下即可,就可以定义匿名对象。

class A
{
public:A(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
int main()
{//无类型名A(2024, 7, 18);
}

 七、拷贝对象时优化

现代编译器会为了尽可能提⾼程序的效率,在不影响正确性的情况下会尽可能减少⼀些传参和传值 过程中可以省略的拷⻉。

class A
{
public:A(int a=100):_a(a){cout << "A(int a)" << endl;}A(const A& aa):_a(aa._a){cout << "A(const A & aa)" << endl;}~A(){cout << "~A()" << endl;}
private:int _a=20;
};
A func1()
{A c;return c;
}
int main()
{//A a;//A b(a);func1();
}

本来函数调用:先构造c、返回值时创建一个c的临时对象。应该是两次构造,2次析构。

但优化后只有一次构造和一次析构

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

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

相关文章

字典树(前缀树)哈希表实现(能查所有字符)

Node2类&#xff1a;表示Trie树的节点。每个节点有三个属性&#xff1a;pass&#xff1a;表示经过该节点的次数&#xff0c;即有多少个字符串经过了这个节点。 end&#xff1a;表示以该节点结尾的字符串数量&#xff0c;即有多少个字符串在这个节点结束。 nexts&#xff1a;是一…

【数据脱敏】⭐️SpringBoot 整合 Jackson 实现隐私数据加密

目录 &#x1f378;前言 &#x1f37b;一、Jackson 序列化库 &#x1f37a;二、方案实践 2.1 环境准备 2.2 依赖引入 2.3 代码编写 &#x1f49e;️三、接口测试 &#x1f379;四、章末 &#x1f378;前言 小伙伴们大家好&#xff0c;最近也是很忙啊&#xff0c;上次的文章…

C++与VLC制作独属于你的动态壁纸背景

文章目录 前言效果展示为什么要做他如何实现他实现步骤获取桌面句柄代码获取桌面句柄libvlc_media_player_set_hwnd函数 动态壁纸代码 总结 前言 在当今的数字世界中&#xff0c;个性化和自定义化的体验越来越受到人们的欢迎。动态壁纸是其中一种很受欢迎的方式&#xff0c;它…

【教学类-70-01】20240722镜子花边(适配5CM圆镜)

背景需求 我想给孩子们做一个小圆镜&#xff0c;花边涂色&#xff0c;打洞&#xff0c;做一个项链样式 1、使用通义万相生成了“圆形镜子&#xff0c;有花边” 边缘细&#xff0c;黑色面积大的图片放到另外一个文件夹里&#xff08;不用&#xff09; 从性价比角度&#xff…

Qt窗口介绍

Qt窗口 一、Qt窗口二、菜单栏创建菜单栏在菜单栏中添加菜单创建菜单项在菜单项之间添加分割线综合练习 三、工具栏创建工具栏设置停靠位置设置浮动属性设置移动属性综合练习 四、状态栏状态栏的创建在状态栏中显示实时消息在状态栏显示永久的消息 五、浮动窗口浮动窗口的创建设…

ArcGIS Pro SDK (九)几何 12 多面体

ArcGIS Pro SDK &#xff08;九&#xff09;几何 12 多面体 文章目录 ArcGIS Pro SDK &#xff08;九&#xff09;几何 12 多面体1 通过拉伸多边形或折线构建多面体2 多面体属性3 构建多面体4 通过MultipatchBuilderEx构建多面体5 从另一个多面体构建多面体6 从 3D 模型文件构建…

Vue的计算属性和方法有什么区别

Vue中的计算属性&#xff08;computed&#xff09;和方法&#xff08;methods&#xff09;都是用于处理数据和逻辑的重要特性&#xff0c;但它们之间存在一些关键的区别。以下是两者的主要区别&#xff1a; 1. 缓存性 计算属性&#xff1a;计算属性是基于它们的依赖进行缓存的…

Pytorch实现图像分类-水果数据集分类--深度学习大作业

目录 1.概述 2.设计 3.实现 4.实验 5.总结 1.概述 本次深度学习大作业&#xff0c;我使用AlexNet模型对"Fruits-360"数据集中的两部分水果和蔬菜图片进行分类 2.设计 模型设计&#xff1a;Alexnet网络 卷积层部分&#xff1a;构建了一系列卷积层、激活函数…

【等保测评】服务器——Windows server 2012 R2

文章目录 **身份鉴别****访问控制****安全审计****入侵防范****恶意代码防范****可信验证****测评常用命令** Windows服务器安全计算环境测评 测评对象&#xff1a;Windows server 2012 R2 身份鉴别 &#xff08;高风险&#xff09;应对登录的用户进行身份标识和鉴别&#x…

【爱上C++】list用法详解、模拟实现

文章目录 一&#xff1a;list介绍以及使用1.list介绍2.基本用法①list构造方式②list迭代器的使用③容量④元素访问⑤插入和删除⑥其他操作image.png 3.list与vector对比 二&#xff1a;list模拟实现1.基本框架2.节点结构体模板3.__list_iterator 结构体模板①模板参数说明②构…

CentOS8无论安装更新什么都出现错误: Failed to download metadata for repo ‘AppStream‘

CentOS 已经停止维护&#xff0c;需要将镜像从 mirror.centos.org 更改为 vault.centos.org&#xff0c;依次执行以下命令即可: 1、cd /etc/yum.repos.d/ 2、sed -i s/mirrorlist/#mirrorlist/g /etc/yum.repos.d/CentOS-* 3、sed -i s|#baseurlhttp://mirror.centos.org|baseu…

【无人机】低空经济中5G RedCap芯片的技术分析报告

1. 引言 图一. 新基建&#xff1a;低空经济 低空经济作为一种新兴的经济形态&#xff0c;涵盖了无人机、电动垂直起降飞行器&#xff08;eVTOL&#xff09;、低空物流、空中交通管理等多个领域。随着5G网络的普及和演进&#xff0c;5G RedCap&#xff08;Reduced Capability&a…

Typora 1.5.8 版本安装下载教程 (轻量级 Markdown 编辑器),图文步骤详解,免费领取(软件可激活使用)

文章目录 软件介绍软件下载安装步骤激活步骤 软件介绍 Typora是一款基于Markdown语法的轻量级文本编辑器&#xff0c;它的主要目标是为用户提供一个简洁、高效的写作环境。以下是Typora的一些主要特点和功能&#xff1a; 实时预览&#xff1a;Typora支持实时预览功能&#xff0…

笔记:Enum中FlagsAttribute特性的用法

一、目的&#xff1a;分享Enum中FlagsAttribute特性的用法 在C#中&#xff0c;Enum&#xff08;枚举&#xff09;类型可以使用[Flags]属性来表示一个枚举可以存储多个值。这是通过按位运算符&#xff08;如|&#xff08;或&#xff09;和&&#xff08;与&#xff09;&#…

HarmonyOS应用开发者高级认证,Next版本发布后最新题库 - 多选题序号1

基础认证题库请移步&#xff1a;HarmonyOS应用开发者基础认证题库 注&#xff1a;有读者反馈&#xff0c;题库的代码块比较多&#xff0c;打开文章时会卡死。所以笔者将题库拆分&#xff0c;单选题20个为一组&#xff0c;多选题10个为一组&#xff0c;题库目录如下&#xff0c;…

腾讯云简单部署MYSQL 8.0

1.安装MySQL8.0资源库 yum localinstall https://repo.mysql.com//mysql80-community-release-el7-1.noarch.rpm2.安装MySQL8.0 yum -y install mysql-community-server --nogpgcheck . yum -y install mysql-community-server --nogpgcheck 3.启动MySQL并配置开机自启 sys…

【效率提升】程序员常用Shell脚本

文章目录 常用Shell脚本一. 定期更新分区数据二、获取系统资源的使用情况 常用Shell脚本 一. 定期更新分区数据 在某些场景下&#xff0c;我们需要对N年前某一分区的数据进行删除&#xff0c;并添加今年该对应分区的数据&#xff0c;实现数据的流动式存储。 #!/bin/bash dt$…

【devops】ttyd 一个web版本的shell工具 | web版本shell工具 | web shell

一、什么是 TTYD ttyd是在web端一个简单的服务器命令行工具 类似我们在云厂商上直接ssh链接我们的服务器输入指令一样 二、安装ttyd 1、macOS Install with Homebrew: brew install ttydInstall with MacPorts: sudo port install ttyd 2、linux Binary version (recommend…

引入js的script标签如何做到异步加载

使用defer和async属性后&#xff0c;JavaScript加载和HTML解析之间的关系有所不同。了解这些差异可以帮助优化网页加载性能。 defer属性 行为&#xff1a; 当使用defer属性时&#xff0c;浏览器会异步加载JavaScript文件&#xff0c;不会阻塞HTML的解析。所有带有defer属性的…

Leetcode 3223. Minimum Length of String After Operations

Leetcode 3223. Minimum Length of String After Operations 1. 解题思路2. 代码实现 题目链接&#xff1a;3223. Minimum Length of String After Operations 1. 解题思路 这一题还是比较简单的&#xff0c;其实就是想明白对于任何一个字符&#xff0c;如果其个数在3个或以…