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,一经查实,立即删除!

相关文章

【数据脱敏】⭐️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窗口二、菜单栏创建菜单栏在菜单栏中添加菜单创建菜单项在菜单项之间添加分割线综合练习 三、工具栏创建工具栏设置停靠位置设置浮动属性设置移动属性综合练习 四、状态栏状态栏的创建在状态栏中显示实时消息在状态栏显示永久的消息 五、浮动窗口浮动窗口的创建设…

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 结构体模板①模板参数说明②构…

【无人机】低空经济中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…

腾讯云简单部署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…

神经网络中如何优化模型和超参数调优(案例为tensor的预测)

总结&#xff1a; 初级&#xff1a;简单修改一下超参数&#xff0c;效果一般般但是够用&#xff0c;有时候甚至直接不够用 中级&#xff1a;optuna得出最好的超参数之后&#xff0c;再多一些epoch让train和testloss整体下降&#xff0c;然后结果就很不错。 高级&#xff1a;…

Redis集群部署Windows版本

Redis集群 之前因为数据量的原因&#xff0c;并没有进行Redis集群的配置需要&#xff0c;现在由于数据量大&#xff0c;需要进行集群部署。 最初在windows系统部署&#xff0c;需要Redis的windows版本&#xff0c;但官方没有windows版本&#xff0c;所以需要去gitHub上找由民…

【STM32】MPU内存保护单元

注&#xff1a;仅在F7和M7系列上使用介绍 功能&#xff1a; 设置不同存储区域的存储器访问权限&#xff08;管理员、用户&#xff09; 设置存储器&#xff08;内存和外设&#xff09;属性&#xff08;可缓冲、可缓存、可共享&#xff09; 优点&#xff1a;提高嵌入式系统的健壮…

Bash 学习摘录

文章目录 1、变量和参数的介绍&#xff08;1&#xff09;变量替换$(...) &#xff08;2&#xff09;特殊的变量类型export位置参数shift 2、引用&#xff08;1&#xff09;引用变量&#xff08;2&#xff09;转义 3、条件判断&#xff08;1&#xff09;条件测试结构&#xff08…

Qt+OpenCascade开发笔记(一):occ的windows开发环境搭建(一):OpenCascade介绍、下载和安装过程

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140604141 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

[C++进阶]模板进阶

此篇是学完stl后对于模板的补充 建议先看看这个[C初阶]模板初阶-CSDN博客 一、类模板 此处是对初阶讲过的 1. 类模板的定义格式 template<class T1, class T2, …, class Tn> class 类模板名 {}; 例如我们之前学习过的vector类&#xff1a; template<class T>…

C++中的多路转接技术之epoll

epoll 是干什么的&#xff1f;举个简单的例子 epoll的相关系统调用**epoll_create**和epoll_create1区别 epoll_ctl参数解释 **epoll_wait**参数说明返回值 epoll的使用 **epoll**工作原理epoll的优点(和 **select** 的缺点对应)epoll工作方式**水平触发**Level Triggered 工作…

Springboot 启动时Bean的创建与注入(一)-面试热点-springboot源码解读-xunznux

Springboot 启动时Bean的创建与注入&#xff0c;以及对应的源码解读 文章目录 Springboot 启动时Bean的创建与注入&#xff0c;以及对应的源码解读构建Web项目流程图&#xff1a;堆栈信息&#xff1a;堆栈信息简介堆栈信息源码详解1、main:10, DemoApplication (com.xun.demo)2…