[C++]类和对象(下)

一:再谈构造函数

1.1 构造函数体赋值

        在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值,虽然构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化

        构造函数体中的语句只能将其称为赋初值而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。

1.2 初始化列表

初始化列表:

成员变量的定义(初始化)是在初始化列表中进行的,而构造函数体中可以给成员变量进行赋值

格式:

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

特点:

1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

2. C++11 中内置类型成员变量在类中声明时可以给默认值,默认值就是在初始化列表中使用的

        在初始化列表中给_day初始化为123,其并没有使用成员变量声明时给的缺省值,而_year和_month使用的就是缺省值

2. 类中包含以下成员,必须放在初始化列表位置进行初始化:

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

引用成员变量与const成员变量

        由于引用修饰的变量与const修饰的变量在定义的时候就必须进行初始化,若在函数体中给他们赋值,编译器会报错,因为此时是赋值不是初始化

成员变量的定义是在初始化列表中进行的,所以这两中变量只能在初始化列表中初始化

class Date
{
public:Date(int year, int month, int day,int aa,int &b):_aa(aa),_b(b){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;const int _aa;int& _b;
};

函数体中的成员也可以在初始化列表中进行赋值,两者的使用并不冲突,甚至可以在初始化列表中直接初始化,再在函数体中赋值一遍,但是写两遍没有意义,只需要写一个就好了
 

class Date
{
public:Date(int year, int month, int day,int aa,int &b):_aa(aa),_b(b) ,_year(year),_month(month),_day(day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;const int _aa;int& _b;
};

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

当类中存在自定义类型变量时,编译器会自动调用其默认构造函数,若不存在默认构造函数就会报错,解决报错的方法有两个:

方法一: 补充默认构造函数

方法二: 在初始化列表调用多参数构造函数初始化自定义类型变量

class Time
{
public:Time(int hour, int min){_hour = hour;_min = min;}
private:int _hour;int _min;
};
class Date
{
public:Date(int year, int month, int day,int aa,int &b):_t(1,2){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;Time _t;
};

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

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

1.3 explicit关键字 

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

再许多情景这个类型转换是十分方便的,例如:

 如果在一些情况下不希望有类型转换,可以在构造函数的前面加一个explicit,用explicit修饰构造函数,将会禁止构造函数的隐式转换。

二:static成员 

2.1 概念

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

2.2 特点

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

面试题:实现一个类,计算程序中创建出了多少个类对象

class A
{
public:A() { ++_scount; }  //构造函数A(const A & t) { ++_scount; } //拷贝构造~A() { --_scount; } //析构static int GetACount() { return _scount; } //使用静态成员函数访问静态成员
private:static int _scount;
};
int A::_scount = 0;
void TestA()
{cout << A::GetACount() << endl;A a1, a2;A a3(a1);cout << A::GetACount() << endl;
}

三: 友元

        友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用

3.1 友元函数

        在类外如果一个函数想要访问类中的私有成员,除了将类的成员改为共有的方法外,友元函数也可以解决这个问题

        友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字

class A
{friend int func(A& a);
private:int _aa;
};
int func(A& a)
{int b = a._aa;return b;
}

说明:

  • 友元函数可访问类的私有和保护成员,但不是类的成员函数
  • 友元函数不能用const修饰
  • 友元函数可以在类定义的任何地方声明,不受类访问限定符限制
  • 一个函数可以是多个类的友元函数
  • 友元函数的调用与普通函数的调用原理相同
     

3.2 友元类

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

class Date
{friend class Time; //Time类是Date类的友元类,则Time类中可以访问Date类中的私有成员
public:Date(int year=2024, int month=2, int day=6){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
class Time
{
public:Time(int hour = 10, int min = 9){_hour = hour;_min = min;}void Print(){cout << d._year << " " << d._month << " " << d._day << endl;}
private:int _hour;int _min;Date d;
};
int main()
{Time t;t.Print();return 0;
}

注意:

1. 友元关系是单向的,不具有交换性

class Date
{friend class Time; //Time类是Date类的友元类,则Time类中可以访问Date类中的私有成员
public:Date(int year=2024, int month=2, int day=6){_year = year;_month = month;_day = day;}//错误::Time类是Date类的友元类,则Time类中可以访问Date类中的私有成员,但是Date类不能访问Time类的成员,除非Date也是Time的友元类void Print(){cout << t._year << " " << t._month << " " << dt_day << endl; //error}
private:int _year;int _month;int _day;Time t;
};
class Time
{
public:Time(int hour = 10, int min = 9){_hour = hour;_min = min;}void Print(){cout << d._year << " " << d._month << " " << d._day << endl;}
private:int _hour;int _min;Date d;
};

2.友元关系不能传递,如果C是B的友元, B是A的友元,则不能说明C时A的友元


3.友元关系不能继承

四.内部类

概念:

      如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。

特性:

1. sizeof(外部类)=外部类,和内部类没有任何关系

因为类只是声明,内部类没有定义出来,sizeof(A)的大小不算内部类

2.内部类是外部类的友元类(外部类不是内部类的友元类)

class A
{
public:class B{public://内部类可以访问外部类的私有成员,但外部类不能访问内部类的私有成员void func(A& a){cout << a._aa << a._bb << endl;}private:int a;};
private:int _aa;int _bb;
};

3.内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。

class A
{
private:static int k;int h;
public:class B {public:void func(const A& a){cout << k << endl;//OKcout << a.h << endl;//OK}};
};
int A::k = 1

五:匿名对象

定义方法: 类名(参数)

class A
{
public:A(int a=1,int b=2):_aa(a),_bb(b){}
private:int _aa;int _bb;
};
int main()
{//有名对象A a1();A a2(10,20);//匿名对象A();A(10, 20);
}

 注意:

  •  匿名对象的声明周期只有定义的这一行

  • 匿名对象常用情景:

        当构造一个函数仅仅只为了调用其成员函数时,可以利用匿名对象调用,这样调用完成后到下一行匿名对象就销毁了

class A
{
public://构造函数A(int a = 1, int b = 2):_aa(a),_bb(b){}void func(){cout << "func" << endl;}
private:int _aa;int _bb;
};
int main()
{//普通方法:A a1;a1.func();//匿名对象A().func();return 0;
}

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

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

相关文章

AI监控+智能充电桩系统如何缓解新能源汽车充电难问题

在新能源汽车行业的快速发展中&#xff0c;充电桩作为重要的配套设施&#xff0c;其建设和发展至关重要。随着新能源汽车销量的增长&#xff0c;补能需求也日益迫切&#xff0c;这为充电桩行业的发展提供了巨大的机遇。然而&#xff0c;充电桩行业在快速发展的同时&#xff0c;…

私人银行市场调研:投资资产总规模将突破90万亿元

私人银行目标客户是具有富裕的资产或很高收入的私人顾客"私人银行的门槛很高&#xff0c;其服务对象不是一般大众客户&#xff0c;而是社会上的富裕人士&#xff0c;或称为高净资产客户(HNw-HighNetworth)。私人银行客户的金融资产一般在100万美元以上&#xff0c;远远高于…

Java设计模式-责任链模式

责任链模式 一、概述二、结构三、案例实现四、优缺点五、源码解析 一、概述 在现实生活中&#xff0c;常常会出现这样的事例&#xff1a;一个请求有多个对象可以处理&#xff0c;但每个对象的处理条件或权限不同。例如&#xff0c;公司员工请假&#xff0c;可批假的领导有部门…

Vue中对虚拟DOM的理解

作为现代前端开发中的主流框架之一&#xff0c;Vue.js是一个非常流行的JavaScript框架&#xff0c;其核心概念之一就是虚拟DOM&#xff08;Virtual DOM&#xff09;。在本篇文章中&#xff0c;我们将深入探讨Vue中虚拟DOM的概念&#xff0c;并讨论为什么它在前端开发中如此重要…

git 合并多条提交记录

我要合并多条提交记录&#xff08;合并前7条为一条&#xff09;&#xff0c;实现如下效果&#xff1a; 使用git rebase // 查看前10个commit git log -10 // 将7个commit压缩成一个commit&#xff1b;注意&#xff1a;vim编辑器 git rebase -i HEAD~4 // add已经跟踪的文件 g…

Qt 常见容器类用法(二)

目录 QList类 QLinkedList类 QList类 对于不同的数据类型&#xff0c;QList<T>采取不同的存储策略&#xff0c;存储策略如下&#xff1a; 如果T是一个指针类型或指针大小的基本数据类型(该基本类型占有的字节数和指针类型占有的字节数相同)&#xff0c;QList<T>…

pytorch基本数据类型

目录 1. tensor2. 数据类型3. 数据类型的创建和使用3.1 数据类型check3.2 Dimension为0的tensor3.2 Dimension为1的tensor3.3 Dimension为2的tensor3.4 Dimension为3的tensor3.5 Dimension为4的tensor 1. tensor 下图为python数据类型与pytorch的对应关系 在pytorch中是没有s…

STM32 硬件随机数发生器(RNG)

STM32 硬件随机数发生器 文章目录 STM32 硬件随机数发生器前言第1章 随机数发生器简介1.1 RNG主要特性1.2.RNG应用 第2章 RNG原理框图第3章 RNG相关寄存器3.1 RNG 控制寄存器 (RNG_CR)3.2 RNG 状态寄存器 (RNG_SR)3.3 RNG 数据寄存器 (RNG_DR) 第3章 RNG代码部分第4章 STM32F1 …

前端vite+vue3——自动化配置路由布局

文章目录 ⭐前言&#x1f496;vue3系列文章 ⭐ 自动化配置路由&#x1f496;引入vite版本自定义目录映射&#x1f496;自动化读取文件下的路由&#x1f496;main入口加载路由&#x1f496;入口app.vue配置&#x1f496;layout基础布局配置&#x1f496;效果 ⭐总结⭐结束 ⭐前言…

Stable Diffusion 模型下载:Samaritan 3d Cartoon SDXL(撒玛利亚人 3d 卡通 SDXL)

文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 由“PromptSharingSamaritan”创作的撒玛利亚人 3d 卡通类型的大模型&#xff0c;该模型的基础模型为 SDXL 1.0。 条目内容类型大模型基础模型SDXL 1.0来源CIVITA…

Linux------命令行参数

目录 前言 一、main函数的参数 二、命令行控制实现计算器 三、实现touch指令 前言 当我们在命令行输入 ls -al &#xff0c;可以查看当前文件夹下所有文件的信息&#xff0c;还有其他的如rm&#xff0c;touch等指令&#xff0c;都可以帮我们完成相应的操作。 其实运行这些…

8.0 Zookeeper 四字命令教程详解

zookeeper 支持某些特定的四字命令与其交互&#xff0c;用户获取 zookeeper 服务的当前状态及相关信息&#xff0c;用户在客户端可以通过 telenet 或者 nc&#xff08;netcat&#xff09; 向 zookeeper 提交相应的命令。 安装 nc 命令&#xff1a; $ yum install nc …

算法提升——LeetCode123场双周赛总结

周赛题目 三角形类型 II 给你一个下标从0开始长度为3的整数数组nums&#xff0c;需要用它们来构造三角形。 如果一个三角形的所有边长度相等&#xff0c;那么这个三角形称为equilateral。 如果一个三角形恰好有两条边长度相等&#xff0c;那么这个三角形称为isosceles。 如…

【Docker】Docker Image(镜像)

文章目录 一、Docker镜像是什么&#xff1f;二、镜像生活案例三、为什么需要镜像四、镜像命令详解docker rmidocker savedocker loaddocker historydocker image prune 五、镜像操作案例六、镜像综合实战实战一、离线迁移镜像实战二、镜像存储的压缩与共享 一、Docker镜像是什么…

Python学习路线 - Python高阶技巧 - 拓展

Python学习路线 - Python高阶技巧 - 拓展 闭包闭包注意事项 装饰器装饰器的一般写法(闭包写法)装饰器的语法糖写法 设计模式单例模式工厂模式 多线程进程、线程并行执行多线程编程threading模块 网络编程Socket客户端和服务端Socket服务端编程实现服务端并结合客户端进行测试 S…

华为豪掷770亿分红 至少将惠及14万人

华为技术有限公司近期发布的各项信息显示其在ICT领域的持续创新和稳健经营&#xff1a; 华为最近公布了2023年的分红方案&#xff0c;计划分红总额达770.85亿元&#xff0c;该分红将惠及14万员工&#xff0c;人均可获得约54.2万元1678910。此次分红的税后收益率是15.3%&#xf…

正则表达式与文本处理工具

目录 引言 一、正则表达式基础 &#xff08;一&#xff09;字符匹配 1.基本字符 2.特殊字符 3.量词 4.边界匹配 &#xff08;二&#xff09;进阶用法 1.组与引用 2.选择 二、命令之-----grep &#xff08;一&#xff09;基础用法 &#xff08;二&#xff09;高级用…

K8s 集群可观测性-数据分流最佳实践

简介 在微服务架构下&#xff0c;一个 k8s 集群中经常会部署多套业务&#xff0c;同时也意味着不同团队、不同角色、不同的业务会在同一集群中&#xff0c;需要将不同业务的数据在不同的空间进行管理和查看。 在传统的主机环境下&#xff0c;这个是可以通过不同的主机部署 Da…

百面嵌入式专栏(面试题)内存管理相关面试题1.0

沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将介绍内存管理相关面试题 。 一、内存管理相关面试题 page数据结构中的_refcount和_mapcount有什么区别?匿名页面和高速缓存页面有什么区别?page数据结构中有一个锁,我们称为页锁,请问trylock_page()和loc…

协程模式在Android中的应用及工作原理

协程模式在Android中的应用及工作原理 在Android开发中&#xff0c;很多开发者通过代码模式学习协程&#xff0c;通常这已经足够应付了。但这种学习方式忽略了协程背后的精髓&#xff0c;事实上&#xff0c;它们的原理非常简单。那么&#xff0c;是什么使得这些模式起作用呢&a…