lesson04:类和对象(下)

1. 再谈构造函数

2.static成员

3.友元

4.内部类

5.匿名对象

1. 再谈构造函数

1.1构造函数体内赋值

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
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()
{return 0;
}

构造函数体种的语句只能将其称为赋值,不能叫做初始化。

它是不能够做到给const数据成员初始化的。

1.2初始化列表

以一个冒号开始,接着是一个以逗号分隔的数据成员列表,没个数据成员后面有一个小括号,括号里面写用于初始化的初始值或表达式

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:Date(int year, int month, int day): _year(year)//初始值, _month(month), _day(day),arr((int*)malloc(sizeof(int)))//表达式{}
private:int _year;int _month;const int _day;int* arr;
};
int main()
{return 0;
}

1.每个数据成员再1初始化列表中只能出现一次(初始化只能进行一次)

2.类中包含以下成员,必须在初始化列表初始化

引用成员变量

const成员变量

自定义类型成员(且没有默认构造函数)

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class A
{
public:A(int a):_a(a){}
private:int _a;
};
class B
{
public:B(int a, int ref):_aobj(a), _ref(ref), _n(10){}
private:A _aobj;// 没有默认构造函数int& _ref;// 引用const int _n; // const 
};
int main()
{B d(1, 2);return 0;
}

3.尽量使用初始化列表初始化。

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

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class A
{
public:A(int a):_a1(a), _a2(_a1){}void Print() {cout << _a1 << " " << _a2 << endl;}
private:int _a2;int _a1;
};
int main() {A aa(1);aa.Print();return 0;
}

因为_a2是先声明的,所以先对_a2初始化,由于此时_a1还没被初始化,所以_a1是随机值,所以_a2被初始化成了随机值。

5.缺省值与初始化列表的联系

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class A
{
public:void Print() {cout << _a1 << " " << _a2 << endl;}
private:const int _a2 = 1;const int _a1 = 2;
};
int main() {A aa;aa.Print();return 0;
}

上面说过,const数据成员一定要在初始化列表初始化,那这里没写,为什么是对的呢?难道是在声明时初始化吗?

解答:

1.编译器默认生成了初始化列表

2.没有声明时初始化这个说法,这种写法是给缺省值,如果不为数据成员指定初始化的内容,那么将使用这个缺省值。所以,编译器是将这个缺省值给到初始化列表,然后再由初始化列表对数据成员初始化。

补充:缺省值也是可以给表达式的

1.3类型转换

内置类型的变量可以通过类型转换变为自定义类型的对象。

而类型转换是通过构造函数实现的。

1.3.1给构造函数传1个参数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:int _a;Date(int a):_a(a){}
};
int main() 
{Date d = 3;cout << d._a;return 0;
}
1.3.2给构造函数传多个参数
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:int _a;int _b;Date(int a, int b):_a(a), _b(b){}
};
int main() 
{Date d = { 3,5 };cout << d._a << endl << d._b;return 0;
}

1.4explicit关键字

explicit修饰构造函数,禁止类型转换

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:int _a;int _b;explicit Date(int a, int b):_a(a), _b(b){}
};
int main() 
{Date d = { 3,5 };//无法类型转换,报错cout << d._a << endl << d._b;return 0;
}

2.static成员

2.1概念

用static修饰成员变量,称为静态成员变量; 用static修饰成员函数,称为静态成员函数

2.2特性

1.静态成员所有类对象所共享,不属于某个具体的对象,存放在静态区。

2.静态成员变量必须在类外定义,定义不加static,要使用作用域运算符说明该静态成员变量来自哪个类。注意:类中的只是声明,且静态成员只能在全局定义

3.类静态成员可用类名::静态成员或者对象.静态成员访问。

4.静态成员函数没有this指针,不能访问非静态成员(包括成员函数,调用成员函数也需要this指针)。

5.静态成员也是类的成员,受public,protect,private限制。(定义时无限制)

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:static int a;static void test(){//cout << c;报错,不能访问非静态成员//test1();报错,非静态成员函数也不能cout << b;//静态成员可以test2();}static void test2() {};void test1() {};
private:static int b;int c = 1;
};
int Date::a = 5;//类外定义,不加static,用::说明a来源于Date类
int Date::b = 1;//只能在全局初始化
int main() 
{Date d;cout << Date::a << endl;//类名::静态成员访问cout << d.a << endl;//对象.静态成员访问//cout << Date::b;报错,受public限制return 0;
}

3.友元

友元函数提供了一种突破封装的方式,提供了便利,但同时破坏了封装。(不宜多用

友元分为:友元函数友元类

3.1友元函数

3.1.1概念

友元函数时定义在类外普通函数,不属于任何类,但需要在类内友元声明(和之前的声明一样写,最后在声明开头加上friend)。

3.1.2特性

1.友元函数可以访问类的私有和保护成员

2.一个函数可以是多个类的友元函数

3.友元函数可以在类内任何位置声明,不受private,protect,public限制

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date;//在A类中对test函数友元声明要用到Date,此时Date还为声明//这种写法不算重定义,这么写只是向编译器说明该源文件中有//Date类,和函数的声明一样。
class A
{friend void test(const Date& d, const A& t);
private:int a = 2;
};
class Date
{friend void test(const Date& d, const A& t);
private:int a = 1;};
void test(const Date& d, const A& t)
{cout << d.a << endl;//访问私有成员cout << t.a << endl;
}
int main()
{Date d;A t;test(d, t);return 0;
}

注意:编译器通过花括号的有无来判断是声明还是定义,若有花括号,则是定义;若无花括号,则是声明

3.2友元类

3.2.1概念

将一个类在另一个类中友元声明(和之前的声明一样写,最后在声明开头加上friend),那么该类称为另一个类的友元类,该类中的所有成员函数都是另一个类的友元函数

3.2.2特性

1.友元是单向的

如果A是B的友元,不能说明B是A的友元,此时,A能访问B的私有,但B不能访问A的私有

2.友元关系不能传递 

如果C是B的友元,B是A的友元,不能说明C是A的友元

3.友元关系不能继承(以后讲)

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class A
{friend class Date;//友元声明int b = 1;int a = 2;
};
class Date
{int a = 1;
public:void test(const A& a){cout << a.a << endl << a.b << endl;//访问A类的私有成员}
};
int main()
{Date d;A a;d.test(a);return 0;
}

4.内部类

4.1概念

如果一个类的定义在另一个类的内部,那么该类就叫内部类。内部类是一个独立的类,不属于任何外部类。

4.2特性

1.内部类可以通过对应外部类的对象访问私有成员。注意:本质上,内部类就是外部类的友元类。但是,外部类不是内部类的友元类。

2.内部类可以直接访问对应外部类的静态成员(不需要通过类名或对象访问,通过类名或对象访问也是对的)

3.对外部类计算大小时,不计入内部类的部分(内部类是一个独立的类,不属于任何外部类。)

4.不能通过外部类的对象直接访问内部类的成员;内部类也不能直接访问外部类的非静态成员(内部类是一个独立的类,不属于任何外部类。)

注意:可以用内部类的对象间接访问

5.内部类受外部类的类域限制(类域类似于命名空间域)

6.内部类受private等访问限定符的限制

总结:友元性,静态直接访问性,受限制性,独立性(作者自己编的名字,无权威)

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:class A1{};int a = 1;static int b;
public:class A2{private:int e = 4;public:int d = 3;void test(const Date& d){//cout << a;报错,不能直接访问外部类的非静态成员cout << b << endl;//可以直接访问外部类的静态成员cout << Date::b << endl;//间接访问也对cout << d.b << endl;cout << d.a << endl;//可以间接访问外部类的非静态成员//内部类是外部类的友元类,可以访问静态成员}};void test(const A2& a){//cout << d; 报错,不能直接访问内部类cout << a.d << endl;//可以间接访问//cout << a.e; 报错,外部类不是内部类的友元}
};
int Date::b = 2;
int main()
{//A2 a; 报错,内部类受类域限制//Date::A1 a1; 报错,内部类受private限制Date::A2 a2;Date d;a2.test(d);d.test(a2);return 0;
}

5.匿名对象

5.1概念

顾名思义,匿名对象就是没有名字的对象

5.2特性

1.生命周期只在当前语句

2.定义方法:类名(参数);  

注意:这里的参数是传给构造函数的

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:int _a = 2;Date(){cout << "Date()" << endl;}Date(int a):_a(a){cout << "Date(int a)" << endl;}~Date(){cout << "~Date()" << endl;}
};
int main()
{Date(1);cout << "11111111111" << endl;Date();return 0;
}

 

3.如果不给构造函数传参,括号必须写

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:int _a = 2;Date(){cout << "Date()" << endl;}Date(int a):_a(a){cout << "Date(int a)" << endl;}~Date(){cout << "~Date()" << endl;}
};
int main()
{Date;//这里虽然没报错,但是对象没有创建return 0;
}

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

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

相关文章

Oceanbase体验之(二)Oceanbase集群的搭建(社区版4.2.2)

资源规划 3台observer CPU:4C及以上 内存&#xff1a;32G及以上 硬盘操作系统500G 存储盘1T及以上 虚拟机可以直接划分&#xff0c;物理机需要提前规划好资源 一、上传oceanbase安装包 登录ocp选择软件包管理 上传Oceanbase软件包&#xff08;软件包获取路径 官网免费下载社…

【量化】基于遗传规划的因子自动挖掘系统

最后&#xff1a;策略达到了23.6%的年化收益&#xff0c;夏普比率达到5.87&#xff0c;最大回撤为-4.3%&#xff0c;平局年换手率为27.45 倍&#xff0c;平均持股数量为543 支。 文末有回测结果。 目录 1.模型思想 1.1遗传规划算法介绍 ​1.2因子测试流程 2.代码与实现 2.1…

云原生Kubernetes: K8S 1.29版本 部署Nexus

目录 一、实验 1.环境 2.搭建NFS 3. K8S 1.29版本 部署Nexus 二、问题 1.volumeMode有哪几种模式 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构版本IP备注masterK8S master节点1.29.0192.168.204.8 node1K8S node节点1.29.0192.168.204.9node2K…

【yolo算法道路井盖检测】

yolo算法道路井盖检测 数据集和模型yolov8道路井盖-下水道井盖检测训练模型数据集pyqt界面yolov8道路井盖-下水道井盖检测训练模型数据集 算法原理 1. 数据集准备与增强 数据采集&#xff1a;使用行车记录仪或其他设备收集道路井盖的图像数据。数据标注&#xff1a;对收集到…

网络协议深度解析:SSL、 TLS、HTTP和 DNS(C/C++代码实现)

在数字化时代&#xff0c;网络协议构成了互联网通信的基石。SSL、TLS、HTTP和DNS是其中最关键的几种&#xff0c;它们确保了我们的数据安全传输、网页的正确显示以及域名的正常解析。 要理解这些协议&#xff0c;首先需要了解网络分层模型。SSL和TLS位于传输层之上&#xff0c…

【Java--数据结构】链表经典OJ题详解(上)

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 谈谈头插、头删、尾插、头插的时间复杂度 反转一个单链表 链表的中间结点 返回倒数第k个结点 合并两个链表 谈谈头插、头删、尾插、头插的时间复杂度 头插和头删的时…

使用react-vant上传图片遇到的问题

使用react-vant Uploader上传图片后出现的问题。 先试用upload上传图片。 <Form.Itemrules{[{ required: true, message: 请上传头像 }]}label上传头像namefiles><Uploader accept* maxCount"1" onChange{imgFile} /></Form.Item> 图片上传成功后…

Linux网络-DNS域名解析服务

目录 一.DNS相关介绍 1.DNS是什么 2.DNS系统的分布式数据结构 根域 顶级域 二级域 子域 主机 3.服务器类型 主域名服务器 从域名服务器 缓存域名服务器 转发域名服务器 二.DNS域名解析 1.DNS域名解析方式及功能 2.DNS域名解析查询方式 2.1.递归查询&#xff0…

OpenWRT设置自动获取IP,作为二级路由器

前言 上一期咱们讲了在OpenWRT设置PPPoE拨号的教程&#xff0c;在光猫桥接的模式下&#xff0c;OpenWRT如果不设置PPPoE拨号&#xff0c;就无法正常上网。 OpenWRT设置PPPoE拨号教程 但现在很多新装的宽带&#xff0c;宽带师傅为了方便都会把光猫设置为路由模式。如果你再外…

微软在汉诺威工业博览会上推出新制造业Copilot人工智能功能,强化Dynamics 365工具集

在近日于德国汉诺威举行的盛大工业博览会上&#xff0c;微软向全球展示了其最新推出的制造业人工智能功能&#xff0c;这些功能以Dynamics 365工具集为核心&#xff0c;旨在通过先进的AI技术为制造业带来前所未有的变革。 此次推出的新功能中&#xff0c;最为亮眼的是支持AI的…

数据可视化(四):Pandas技术的高级操作案例,豆瓣电影数据也能轻松分析!

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

Blueprints - 鼠标光标判断相关节点

一些以前的学习笔记归档&#xff1b; 俯视角场景中要用鼠标光标判断是否点中物体&#xff0c;或依靠光标引发各种事件&#xff1b; 这些逻辑一般编写在Controller中&#xff0c;Controller类本身就带有相关判断节点&#xff1a; 其中Get Hit Result Under Cursor by Channel是…

如何批量跟踪京东物流信息

随着电商行业的快速发展&#xff0c;快递业务日益繁忙&#xff0c;无论是商家还是消费者&#xff0c;都需要一种高效、便捷的快递查询工具。快递批量查询高手软件应运而生&#xff0c;以其强大的功能和便捷的操作体验&#xff0c;赢得了广大电商、微商精英们的青睐。 快递批量…

机器人视觉教学实训平台

一&#xff1a;功能概述 1.1、功能简介 机器人视觉教学实训平台基于睿尔曼机器人与海康机器视觉产品&#xff0c;面向机器人视觉系统应用而开发设计&#xff0c;产品涵盖机器人系统、工业视觉系统、自动化控制系统、计算机编程系统&#xff0c;可以在一台设备上进行多种与机器…

冷热不均?试试智慧供热二网平衡解决方案吧!

一、系统背景&#xff1a; 在城市供热系统中&#xff0c;目前普遍存在热力平衡调节困难、过量供热及供热不足并存、系统灵活性不足、管理粗放、智能化水平不高、无法根据实际天气变化及具体需求灵活调节等问题。供水管和回水管之间的温差过大&#xff0c;导致热能在循环过程中…

Confluence 快捷键大揭秘:提高效率的小窍门

使用 Confluence 快捷键的好处有&#xff1a; 1.提高工作效率&#xff1b; 2.更流畅地进行编辑、导航和管理操作&#xff1b; 3.减少误操作&#xff1b; 4.展现专业水平。 更多精彩内容&#xff1a; 成为 Jira 大师&#xff1a;效率达人的必备秘诀 Jira Cloud 项目管理专栏 PMO…

Linux:进程创建 进程终止

Linux&#xff1a;进程创建 & 进程终止 进程创建fork写时拷贝 进程终止退出码strerrorerrno 异常信号exit 进程创建 fork fork函数可以用于在程序内部创建子进程&#xff0c;其包含在头文件<unistd.h>中&#xff0c;直接调用fork()就可以创建子进程了。 示例代码&…

个人博客系统的设计与实现

https://download.csdn.net/download/liuhaikang/89222885http://点击下载源码和论文 本 科 毕 业 设 计&#xff08;论文&#xff09; 题 目&#xff1a;个人博客系统的设计与实现 专题题目&#xff1a; 本 科 毕 业 设 计&#xff08;论文&#xff09;任 务 书 题 …

算法-动态规划专题

文章目录 前言 : 动态规划简述1 . 斐波那契模型1.1 泰波那契数列1.2 最小花费爬楼梯1.3 解码方法 前言 : 动态规划简述 动态规划在当前我们的理解下,其实就是一种变相的递归,我们查看一些资料也可以知道,动态规划其实属于递归的一个分支,通过把递归问题开辟的栈帧通过一定的手…