C++ --> 类和对象(三)

欢迎来到我的Blog,点击关注哦💕

前言

前面已经对类和对象有一定的了解,接下来再次深入的了解一下。

一、深入理解构造函数

构造函数体赋值:

虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化, 构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体 内可以多次赋值

class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day;
};

初始化列表

初始化列表是在C++中构造函数中用于初始化类成员变量的一种机制。

  • 它以冒号(:)开始,后跟以逗号分隔的成员变量列表,每个成员变量后面可以跟一个初始化表达式。
class Date
{Date(int year, int month, int day):_year(year), _month(month), _day(day){}private:int _year;int _month;int _day;
};

初始化列表使用的关键点:

  1. 初始化顺序:成员变量在初始化列表中的初始化顺序遵循它们在类定义中声明的顺序,而不是初始化列表中出现的顺序。
  • 严格执行声明顺序即初始化顺顺序,下面的代码在语法上先进行capacity的初始化。

    下面的程序会崩溃:

    1. 先进行_a的开辟空间,capacity没有进行初始化
    2. 导致capacity 是随机值。赖皮空间随机值。
class Stack
{
public:Stack(int capacity)//错误:_capacity(capacity), _a((int*)malloc(sizeof(int)* _capacity)),_size(0){}
private:int* _a;int _capacity;int _size;
};
  1. 特定成员的初始化:对于常量成员、引用成员以及没有默认构造函数的自定义类型成员,必须在初始化列表中进行初始化,因为这些成员不能在构造函数体内被赋值。

    • 引用和const修饰都是在初始化定义的。
    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 
    };
    
    1. 性能优势:使用初始化列表可以避免成员变量先默认构造后再赋值的额外步骤,特别是对于资源管理类(如持有指针或动态分配内存的类),这可以提高效率

    2. 成员变量的初始化只能进行一次,无论是在初始化列表中还是在构造函数体内,都不能重复初始化同一个成员变量。

      class Date
      {Date(int year, int month, int day):_year(year), _month(month), _day(day)
      //         ,_day(day)    //在加入这句就是错误的,初始化只能进行一次。{}private:int _year;int _month;int _day;
      };
      
  2. 成员变量的缺省值:如果在类成员声明时指定了缺省值,这些值将在进入构造函数体之前被用于初始化列表

    • 如果在定义的时候进行了传递参数,即优先使用传递的参数。
class Date
{Date(int year, int month, int day):_year(year), _month(month), _day(day){}private:int _year = 1;int _month = 1;int _day = 1;
};
  1. 初始化列表的灵活性:除了初始化成员变量,初始化列表还可以用于动态内存分配、类型转换赋值等操作

二、explicit 关键字

explicit关键字用于修饰类的构造函数,以防止隐式类型转换。当一个构造函数被声明为explicit时,它不能参与隐式转换,只能通过直接初始化或拷贝初始化的方式显式调用。

class Date
{
public:// 1. 单参构造函数,没有使用explicit修饰,具有类型转换作用// explicit修饰构造函数,禁止类型转换---explicit去掉之后,代码可以通过编译explicit Date(int year):_year(year){}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private:int _year;int _month;int _day;
};void Test()
{Date d1(2024);d2 = 2024;
}

三、static成员

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

static成员的特性

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

  2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明

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

  4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员

    在下面的例子中:

    1. 没有this指针 func1 访问不了 func2
    class Date
    {
    public:static void func1(){}void func2(){}private:int _year;int _month;int _day;static int count;
    };
  5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制

四、友元

友元概念

  • 友元(friend)是一种特殊的关系,它允许一个函数或类访问另一个类的私有成员或保护成员。
  • 友元关系不是类的成员关系,而是一种独立的访问权限关系。
  • 通过友元,可以在不破坏封装性的前提下,实现类之间的数据共享和功能协作

修改print:

正常访问"重载操作<<",是访问不到 Date的private成员变量的,friend很好的帮助我们突破了这个界限。

ostream& operator<<(ostream& out,const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}class Date
{friend  ostream& operator<<(ostream& out, const Date& d);public:Date(int year = 1, int month = 1, int day = 1): _year(year), _month(month), _day(day){}private:int _year;int _month;int _day;
};

五、内部类

内部类的特点

  • 独立性:内部类是一个独立的类,不隶属于外部类。
  • 访问权限:内部类可以定义在外部类的任何访问级别中,其访问外部类成员的权限取决于其自身的定义位置。
  • 访问外部类成员:内部类可以直接访问外部类的staticenum成员,但不能直接访问外部类的非静态成员。
  • 大小关系:内部类的大小与外部类无关,sizeof(外部类)不会包括内部类的大小。
  • 创建方式:内部类的对象可以通过外部类的作用域限定符创建,例如外部类名::内部类名
  • 生命周期:内部类的对象可以在栈上或堆上创建,其生命周期取决于创建方式。
{
private:static int k;int h;
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()
{A::B b;b.foo(A());return 0;
}

编程题目:友元的巧妙应用

求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

数据范围: 0<�≤2000<n≤200
进阶: 空间复杂度 O*(1) ,时间复杂度 O*(n)

class Solution {
public:class B{public:B(){ret +=i;++i;}};
int Sum_Solution(int n) {B a[n];return ret;
}private:
static int ret ;
static int i;
};int Solution:: ret = 0;
int Solution:: i = 1;

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

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

相关文章

[笔记] SEW的振动分析工具DUV40A

1.便携式振动分析仪 DUV40A 文档编号&#xff1a;26871998/EN SEW是一家国际化的大型的机械设备供应商。产品线涵盖电机&#xff0c;减速机&#xff0c;变频器等全系列动力设备。DUV40A是他自己设计的一款振动分析工具。 我们先看一下它的软硬件参数&#xff1a; 内置两路传…

防火墙综合实验之NAT和智能选路

目录 前言&#xff1a; 一、实验题目 二、实验操作 需求一 需求二 需求三 需求四、需求五 需求六 需求七 ​编辑 需求八 需求九 需求十 需求十一 三、需求测试 前言&#xff1a; 本篇文章是延续上一篇文章&#xff0c;简单来说就是防火墙实验的完善和延续&#…

CV07_深度学习模块之间的缝合教学(2)--维度转换

教学&#xff08;1&#xff09;&#xff1a;链接 1.1 预备知识 问题&#xff1a;假如说我们使用的模型张量是三维的&#xff0c;但是我们要缝合的模块是四维的&#xff0c;应该怎么办&#xff1f; 方法&#xff1a;pytorch中常用的函数&#xff1a;(1)view函数&#xff08;2…

新华三H3CNE网络工程师认证—DHCP使用场景

网络服务与应用当中的技术有DHCP、Telnet和FTP。DHCP是计算机当中常用来获取地址的。比如日常使用中&#xff0c;计算机并没有接入IP&#xff0c;IP通过DHCP技术从上端服务去获取的。手动配置网络参数会出现多种问题。 文章目录 一、手动配置网络参数的问题1、参数多、理解难2、…

【零基础】学JS之APIS第四天

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

喰星云·数字化餐饮服务系统 多处 SQL注入漏洞复现

0x01 产品简介 喰星云数字化餐饮服务系统是一款专为餐饮企业设计的综合性管理软件,旨在通过信息化手段提升餐饮企业的运营效率、降低运营成本,并实现数据驱动的决策管理。该系统包括供应链管理、财务管理、巡店管理、人力资源管理等多个模块,可全面覆盖餐饮企业的日常运营需…

Zynq7000系列FPGA中的DDR内存控制器

DDR内存控制器是一个高度集成的组件&#xff0c;支持多种DDR内存类型&#xff08;DDR2、DDR3、DDR3L、LPDDR2&#xff09;&#xff0c;并通过精心设计的架构来优化内存访问效率。 DDR内存控制器架构 AXI内存端口接口&#xff08;DDRI&#xff09;&#xff1a;该部分负责处理与…

C/C++指针智能指针二

C/C指针&智能指针二 文章目录 C/C指针&智能指针二1.智能指针简介2.独占智能指针unique_ptr1.基本概念2.使用方法1.初始化 3.使用技巧 3.共享智能指针1.基本概念2.使用方法3.注意事项 4.智能指针删除器1.如何使用删除器2.应用场景 5.弱智能指针weak_ptr1.基本概念2.使用…

雷赛运动控制卡编程(2)限位设定与回原方式、脉冲模式设置

一、限位开关及急停开关的设置 限位开关的设置 //设置限位开关// dmc_set_el_modeushort _cardNo0;ushort _axisNo 0;ushort _enable 1; // 正负限位使能 ushort _elLogic 0; // 正负限位 低电平 有效ushort _model 0;// 正负限位停止方式为立即停止LTDMC.dmc_set_el_m…

构建实用的NLP应用程序:重塑人类与计算机的协同工作方式

文章目录 一、NLP技术的核心价值二、构建实用NLP应用程序的关键步骤三、NLP应用程序在协同工作中的创新应用《赠ChatGPT中文范例的自然语言处理入门书》编辑推荐内容简介作者简介精彩书评目录前言/序言获取方式 在数字化时代&#xff0c;自然语言处理&#xff08;NLP&#xff0…

手机数据恢复:适用于 Android 的 4 大数据恢复应用程序

没有人希望丢失设备上的重要数据。如果发生这种情况&#xff0c;请不要惊慌。以下是可帮助您恢复丢失或删除的数据的 Android 数据恢复应用程序列表。 有多种方法可以恢复已删除或丢失的 Android 数据&#xff0c;最简单、最快捷的方法是使用第三方恢复应用程序。这些应用程序会…

Transformer模型:Postion Embedding实现

前言 这是对上一篇WordEmbedding的续篇PositionEmbedding。 视频链接&#xff1a;19、Transformer模型Encoder原理精讲及其PyTorch逐行实现_哔哩哔哩_bilibili 上一篇链接&#xff1a;Transformer模型&#xff1a;WordEmbedding实现-CSDN博客 正文 先回顾一下原论文中对Posit…

[Windows] 号称最快免费小巧的远程桌面 AnyDesk v8.0.11单文件版

描述 对于经常在互联网上进行操作的学生&#xff0c;白领等&#xff01; 一款好用的软件总是能得心应手&#xff0c;事半功倍。 今天给大家带了一款高科技软件 虽然 QQ 拥有远程协助功能&#xff0c;但很多时候连接并不够流畅&#xff0c;而且被控电脑那方也必须要有人操作才行…

电脑关机被阻止

1. winR输入regedit进入注册表 2. 选择HKEY_USERS-》.DEFAULT-》Control Panel-》Desktop 3. 右键DeskTop新建字符串值&#xff0c;命名为AutoEndTasks&#xff0c;数值设置为1

C++中链表的底层迭代器实现

大家都知道在C的学习中迭代器是必不可少的&#xff0c;今天我们学习的是C中的链表的底层迭代器的实现&#xff0c;首先我们应该先知道链表的底层迭代器和顺序表的底层迭代器在实现上有什么区别&#xff0c;为什么顺序表的底层迭代器更加容易实现&#xff0c;而链表的底层迭代器…

不会编程怎么办?量化交易不会编程可以使用吗?

量化交易使用计算机模型程序代替人工进行交易&#xff0c;一般需要投资者自己编写程序建模&#xff0c;然后回测无误之后再进行实盘交易&#xff0c;那么不会编程的投资者能使用量化软件进行量化交易吗&#xff1f; 不会编程使用量化软件有两种方法 一种是请人代写代码&#x…

Java软件设计模式-单例设计模式

目录 1.软件设计模式的概念 2.设计模式分类 2.1 创建型模式 2.2 结构型模式 2.3 行为型模式 3.单例设计模式 3.1 单例模式的结构 3.2 单例模式的实现 3.2.1 饿汉式-方式1&#xff08;静态变量方式&#xff09; 3.2.2 懒汉式-方式1&#xff08;线程不安全&#xff09; 3.…

职场新人感受

互联网职场感受 阶段介绍 24届6月底毕业生&#xff0c;之前从未实习过。 岗位是后端开发&#xff08;JAVA&#xff09;&#xff0c;目前已经上班三周&#xff08;前两周看文档和做了半个简单需求&#xff0c;第三周脱产新人培训&#xff09;。 职场体验 职场和想象中的工作…

c++ 网络编程udp协议 poco模块

官网资料(需要梯子)&#xff1a;https://pocoproject.org/slides/200-Network.pdf 1、poco是在原生socket之上的封装&#xff0c;底层还是socket&#xff0c;性能低于socket&#xff0c;安全性和实用性高于socket&#xff0c;即使用简便&#xff0c;接口简单 2、udp协议是&…

办公灯多普勒雷达模组感应开关,飞睿智能24G毫米波雷达超低功耗uA级,节能LED灯新搭档

在科技日新月异的今天&#xff0c;节能、环保已经成为我们生活和工作中不可或缺的一部分。作为新时代的办公人&#xff0c;我们不仅要追求高效的工作方式&#xff0c;更要关注我们所使用的设备是否足够环保、节能。今天&#xff0c;我们就来聊聊一个令人兴奋的创新——飞睿智能…