C++之类和对象(下)

目录

初始化列表

static成员

C++11对于非静态成员变量初始化

友元

友元函数

友元类

总结 


初始化列表

我们知道,在学习构造函数时,我们知道对象的成员变量的初始化我们是在构造函数函数体内进行初始化的,还有没有其它初始化成员变量的方法呢

初始化列表就是我们要学习的第二个初始化的方法

在学习初始化列表之前,我们先对以往的在构造函数内部对成员变量进行初始化的操作进行分析,我们直接给出结论,我们称在类内部的成员变量只是对成员变量进行了声明,而没有进行定义,如图所示:

      我们在日期类内部声明了三个成员变量,_year,_month,_day,切记,这里只是对三个成员变量进行了声明,成员变量的定义分为两种情况:

1.如果我们在构造函数体内进行成员变量的初始化操作,那么在进行初始化时,成员变量已经完成了定义,函数体内只是在进行进行变量的赋值而已。因此就这一现象我们不难产生疑问?如果在函数体内对成员变量进行赋值时,此时变量已经完成了定义,此时的赋值操作就相当于是在成员变量定义之后才对成员变量进行了初始化操作,那么对于const成员变量引用成员变量没有默认构造函数的自定义成员变量这些在定义时必须初始化的成员变量还能用这种初始化方式进行初始化吗?当然不行,此时我们就得用第二种方式进行成员变量的初始化操作。

2.如果我们使用初始化列表进行成员变量的初始化操作,就相当于是在变量定义时,对成员变量进行了初始化操作,这对于上述三种必须在定义时就必须进行初始化的成员变量而言是可行的。

相关示例代码如下:

class A {public:A(int a){_a = a;}
private:int _a;
};
class Date {public:Date(int year,int month,int day,int A):_year(year),_month(month),_day(day),_a(10),a(A),_aa(10){}
private:int _year;int _month;int _day;const int _a;int& a;A _aa;
};

重点:对于自定义类型而言,还有一个要注意的问题:当自定义类型成员变量没有默认的构造函数时,我们必须在定义时进行初始化,所以我们必须用初始化列表对其进行初始化。但是当自定义类型成员变量有默认的构造函数时,我们在定义时可以不用初始化,在定义之后初始化也可以,也就意味着有了默认构造函数的成员变量可以在构造函数的函数体内进行初始化。但是,当我们在构造函数体内对有默认构造函数的成员变量初始化时,编译器同时也默认生成了初始化列表调用了自定义成员变量的默认构造函数对其进行了初始化。所以就会存在不管自定义类型的成员变量是否存在默认的构造函数,我们都会生成初始化列表对自定义类型成员变量进行初始化,所以我们干脆让其都在初始化列表中初始化,没有默认构造函数我们自己生成初始化列表为其初始化,有默认构造函数,编译器帮助我们自动生成初始化列表完成初始化。

总结:对于内置类型的成员变量和自定义类型成员变量(有默认构造函数),在构造函数体内部和初始化列表中都可以进行初始化操作,对于const成员变量,引用成员变量,自定义类型成员变量(没有默认构造函数),我们在初始化列表中完成初始化,为了统一我们规定所有的成员变量都在初始化列表中进行初始化。

static成员

之前我们也学习过static关键字,我们知道static可以改变变量的声明周期,比如可以在局部变量之前加上static,从而使局部变量拥有了和全局变量一样的生命周期,在C++也有static关键字,那么它的作用是什么呢?

其实,C++中的static关键字的作用和我们之前学习的是一样的,同样也可以改变变量的生命周期,可以是成员变量的周期,使之属于类及所有的对象,生命周期在整个程序运行期间。

先看如下代码,当静态成员变量为public时:

class A {
public:static int _c;A(int a=1) {_a = a;}
private:int _a;
};
//静态成员变量必须在类外进行定义初始化
int A::_c = 1;int main()
{//再类外实现对静态成员变量的访问,当静态成员变量为pulbic时A a;cout << a._c << endl;cout << A::_c << endl;return 0;
}

解析:静态成员变量必须在类外进行定义初始化。当静态成员变量为public修饰时,我们在类外进行访问,可以通过对象.类::方式去访问。

 当静态成员变量用private修饰时,在类外肯定是不能访问的,所以我们必须在类内提供公共的接口去访问,先看下列代码:

class A {
public:A(int a=1) {_a = a;}//提供公共的接口,普通的成员函数void print(){cout << _c << endl;}//提供公共的接口,static静态成员函数,但是static静态成员函数没有this指针,所以不能访问非静态成员变量,只能访问静态成员变量和成员函数static void print1(){cout << _c << endl;}
private:int _a;static int _c;
};int A::_c = 3;int main()
{//在类外实现对静态成员变量的访问,当静态成员变量为private时A a;//1.通过对象.的方式去访问a.print();//2.通过类::方式去访问A::print1();return 0;
}

解析:如果是private修饰的静态成员变量,我们在类外可以通过公共的接口,即普通的成员函数和静态的成员函数进行访问,但是静态的成员函数因为没有隐藏的this指针,所以只能访问静态成员变量和成员函数,不能访问非静态成员变量。

总而言之,静态的成员函数成员变量都属于整个类和所有对象,都可以可以使用对象.类::的方式去访问。

C++11对于非静态成员变量初始化

我们在学习构造函数时,我们学写了编译器生成的默认构造函数,我们知道默认构造函数对于内置类型是不做初始化处理的,只对自定义类型进行初始化处理,为了改善这种情况,C++11发明了一种新的语法。就是给非静态成员变量声明时顺便给予缺省值。

相关代码如下:

class A
{
public:void print(){cout << a << endl;}
private:int a = 10;int* p =(int*) malloc(40);
};int main()
{A a;a.print();}

整个过程,就相当于是给自定义类型给予了缺省值,当构造函数的初始化列表没有给内置类型赋初始值时,就会使用这个初始值。

运行截图如下,我们发现内置类型确实使用了此缺省值。

友元

友元的概念:友元是一种允许非类成员函数访问类的非公友成员的一种机制,友元可以是函数或者类,通过在类中用关键字friend说明该函数或者类,使得函数或者类获得其私有和保护成员的访问权限,在函数体中访问对象的成员,必须用对象.的方式访问。

友元函数

直接看代码:

class B {friend void print(B& b);
private:int _b=666;
};void print (B& b) {cout << b._b << endl;}
int main()
{B b;print(b);
}

 运行截图如下:

注意: 1.友元函数可以访问类的私有和保护成员,但是它不是成员函数。

            2.注意const不能修饰友元函数,因为友元函数不是成员函数,const只能修饰成员                   函数。

            3.友元函数就是一种普通的函数,用一般函数调用的方式调用即可。

友元类

直接看代码:

class B {friend class A;
private:int _b=888;
};class A
{
public:void print(){cout << b._b << endl;}private:int _a = 10;B b;
};int main()
{A a;a.print();}

再类B中,直接声明,类A是类B的友元类,那么类A就可以访问类B的非公有成员,运行截图如下:

注意: 1.友元类不具有交换性,声明类A是类B的友元,但此时类B不一定是类A的友元,只有声明了类B时类A的友元类之后,两者才可以互相访问彼此的非公有成员。

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

总结 

到了这里类和对象的学习我们就可以告一段落了,类和对象细小的知识点太多,但是这些细小的知识点便是C++学习的精髓所在,望小伙伴们可以反复观看!

本期内容到此结束!^_^

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

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

相关文章

【Linux】telnet命令使用

telnet命令 telnet命令用于使用telnet协议与另一台主机进行通信。如果在没有主机参数的情况下调用telnet&#xff0c;它将进入命令模式&#xff0c;由其提示&#xff08;telnet>&#xff09;指示。在这种模式下&#xff0c;它接受并执行下面列出的命令。如果使用参数调用它…

数字化时代的保镖:实人认证API在身份验证中的角色

前言 随着数字化时代的迅猛发展&#xff0c;个人信息的安全性和隐私保护成为了当今社会中备受关注的话题。在这个背景下&#xff0c;实人认证API崭露头角&#xff0c;成为数字领域中的一项重要技术&#xff0c;为身份验证提供了全新的保障机制。本文将探讨实人认证API在身份验…

本地启动tomcat,打印的日志中中文乱码

修改配置文件 /conf/logging.properties 修改配置项 java.util.logging.ConsoleHandler.encoding 从UTF-8改成GBK

力扣226:翻转二叉树

力扣226&#xff1a;翻转二叉树 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 2&#xff1a; 输入&#xff1a;root [2,1,3]…

git submodule 用法

子仓库启蒙 在根目录执行&#xff1a; git submodule add gitgitee.com:liaosp/dcat-admin-basic-interface.git想要子模块指定的分支&#xff1a; git submodule add -b dev <仓库地址> <子模块路径>这样相当于在根目录上添加了 .gitmodules 信息&#xff0c;相…

如何制定开发计划

如何制定开发计划&#xff0c;很多开发主管跟项目经理在评估开发计划时喜欢把开发叫起来一块评估&#xff0c;结果会发现&#xff0c;三天时间能做好的功能&#xff0c;底下人&#xff08;特别是一些老油条&#xff09;总是会各种理由做不完要五天&#xff0c;其实这是人之常情…

CTF 6

信息收集 话不多说&#xff0c;nmap进行信息收集&#xff01; 存活主机探测 服务版本探测 端口探测 漏洞脚本探测 UDP端口探测 渗透测试 先看看网站的首页&#xff0c;发现了几个用户&#xff1a; 直接先保存下来吧&#xff0c;以防后面会用到。 SQL注入 看到一个read mor…

作高效保密:了解上海迅软DSE四种加密模式在不同场景中的巧妙运用

于企事业单位内部数据存储情况的复杂性&#xff0c;以及不同公司和部门对文件加密的各异需求&#xff0c;单一的加密系统难以满足这种多样化的加密需求。在应对这一挑战的过程中&#xff0c;天锐绿盾提供了四种不同的加密模式&#xff0c;用户可以根据实际情况选择适用的加密模…

《opencv实用探索·十一》opencv之Prewitt算子边缘检测,Roberts算子边缘检测和Sobel算子边缘检测

1、前言 边缘检测&#xff1a; 图像边缘检测是指在图像中寻找灰度、颜色、纹理等变化比较剧烈的区域&#xff0c;它们可能代表着物体之间的边界或物体内部的特征。边缘检测是图像处理中的一项基本操作&#xff0c;可以用于人脸识别、物体识别、图像分割等多个领域。 边缘检测…

C/C++,图算法——布伦特循环检测算法(Brent‘s cycle detection algorithm)的源程序

1 文本格式 // CPP program to implement Brents cycle // detection algorithm to detect cycle in // a linked list. #include <stdio.h> #include <stdlib.h> /* Link list node */ struct Node { int data; struct Node* next; }; /* Th…

在Vivado 仿真器中搭建UVM验证环境(不需要联合modelsim)

Vivado 集成设计环境支持将通用验证方法学 (UVM) 应用于 Vivado 仿真器。Vivado 提供了预编译的 UVM V1.2 库。 &#xff08;1&#xff09;在 Vivado 2019.2 中创建新 RTL 工程。 &#xff08;2&#xff09;单击“添加目录 (Add Directories)”以将“src”和“verif”目录添加…

CCF计算机软件能力认证202309-2坐标变换(其二)(C语言)

ccf-csp计算机软件能力认证202309-2坐标变换&#xff08;其二&#xff09;(C语言版) 题目内容&#xff1a; 问题描述 输入格式 输出格式 样例输入 10 5 2 0.59 2 4.956 1 0.997 1 1.364 1 1.242 1 0.82 2 2.824 1 0.716 2 0.178 2 4.094 1 6 -953188 -946637 1 9 96953…

计算机网络之网络传输,三次握手和四次挥手

网络传输通过高低电压 流 基本类型数组 低电压转高电压&#xff0c;通过网卡 传输模式&#xff1a; 全双工&#xff1a;互相传输且能同时传输 半双工&#xff1a;互相传输但是不能同时传输 单工&#xff1a;单向传输&#xff0c;&#xff08;键盘&#xff0c;显示器&#…

kubernetes详解——从入门到入土(更新中~)

k8s简介 编排工具&#xff1a;系统层面ansible、saltstackdocker容器docker compose docker swarm docker machinedocker compose&#xff1a;实现单机容器编排docker swarm&#xff1a;实现多主机整合成为一个docker machine&#xff1a;初始化新主机mesos marathonmesos …

微信小程序查看接口信息(抓包)

本文仅供交流学习使用 主要参考: https://cloud.tencent.com/developer/article/1833591 https://www.cnblogs.com/x1you/p/12033839.html 由于参考文章在baidu权重不高(google才查到的), 所以自己重新记录一篇, 方便他人, 也防止参考文章丢失. 背景 需要知道微信小程序的接口…

8、Broker进一步了解

1、Broker消息分发服务以及构建ConsumeQueue和IndexFile与消息清除 前面分析如何进行刷盘&#xff0c;本章分析Broker的消息分发以及构建ConsumerQueue和IndexFile&#xff0c;两者构建是为了能够提高效率&#xff0c;减少消息查找时间以及减少网络带宽与存储空间。 ConsumeQ…

mac电池最大充电限制工具 AlDente Pro中文 for Mac

Pro 版特有功能 热保护&#xff1a;在电池温度较高时为电池充电会导致电池老化更快。启用热保护后&#xff0c;当电池温度过高时&#xff0c;充电将自动停止。 航行模式&#xff1a;通常情况下&#xff0c;即使激活了最大电池充电&#xff0c;您的 MacBooks 电池也会始终稍微充…

7.上传project到服务器及拉取服务器project到本地、更新代码冲突解决

1.上传project到SVN服务器 1.在eclipse中&#xff0c;从show view里调出SVN资源库视图 2.在SVN资源库窗口的空白位置右键选择新建资源库位置 3.填好服务器的地址 4.资源库导入成功,SVN资源库视图下出现导入的资源库 5.新建project 6.写好project的初始版本 7.右键project --&…

激光雷达生成的图像检测关键点用来辅助里程计的方案

文章&#xff1a;LiDAR-Generated Images Derived Keypoints Assisted Point Cloud Registration Scheme in Odometry Estimation 作者&#xff1a;Haizhou Zhang , Xianjia Yu, Sier Ha , Tomi Westerlund 编辑&#xff1a;点云PCL 欢迎各位加入知识星球&#xff0c;获取PDF…

数据结构与算法编程题41

线性表中各结点的检索概率不等时&#xff0c;可用如下策略提高顺序检索的效率&#xff1a; 若找到指定的结点&#xff0c;则将该结点和其前驱结点&#xff08;若存在&#xff09;交换&#xff0c;使得经常被检索 的结点尽量位于表的前端。试设计在顺序结构的线性表上实现上述策…