C++类和对象--中阶

news2025/5/13 16:40:00

C++类和对象中阶

01. 类的6个默认成员函数

在 C++ 中,类有 6 个特殊的默认成员函数(不是 6 个构造函数),它们会在特定情况下由编译器自动生成。包括构造函数,析构函数,拷贝构造和赋值运算符重载,取地址和const取地址重载。简而言之就是,用户没显式实现,编译器会生成的成员函数。


02. 构造函数

2.1 构造函数概念

构造函数是特殊的成员函数,对象创建是自动调用并且初始化对象。如果类中没有定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。

构造顺序:基类 → 成员对象 → 派生类。

2.2 构造函数特性

  • 函数名与类名相同,无返回值(连 void 都没有)。
  • 自动调用,不可手动调用。
  • 可以有参数(支持重载)。

默认构造函数:

我们不传参(编译器生成随机值)就可以调用的(如:Date d;),有三种,但是不能同时存在。包括无参形式 ,编译器生成和全缺省的形式,。编译器生成默认的构造函数会对自定类型成员_t调用的它的默认成员函数。

class Date {
public:
    Date() {  // 无参
    }
    Date(int year = 0, int month = 1,int day=1) {  // 全缺省
        _year = year;
        _month = month; 
        _day = day;
    }
    //不写
private:
        _year;
        _month; 
        _day;
};

带初始化列表形式

在构造函数体执行前初始化成员变量。

...
    public:
		Date(int year = 0, int month = 1,int day=1) {  // 初始
       :_year(year);
      	_month(month), 
        _day(day);
    }
...

03. 析构函数

3.1 析构函数概念

与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。销毁那个类的对象则调用该类的析构函数。

析构顺序:派生类 → 成员对象 → 基类(与构造相反)

3.2 析构函数特点

  • 函数名为 ~ClassName,无参数和返回值
  • 对象生命周期结束时自动调用
  • 一个类只能有一个析构函数,若未显式定义,系统自动生成

动态内存(new/delete)关闭、释放等。

~Stack(){
 if (_array){
 	free(_array);
	 _array = NULL;
	 _capacity = 0;
	 _size = 0;
 }
}

06. 拷贝构造函数

拷贝构造函数是一种特殊的构造函数,用于通过一个已存在的对象来初始化一个新对象。Date od2 = d1或Date od2(d1)都是拷贝构造。白话:构造一个d2,它和d1一模一样,d1变化他也随着变化!拿一个同类型的构造。

使用场景:

  • 用一个对象初始化另一个对象(如:Date od2 = d1或Date od2(d1)

  • 对象作为函数参数按值传递

传值形式拷贝构造问题:

当参数 d 是值传递时,调用拷贝构造函数时需要先复制实参到形参 d,而复制 d 又会调用拷贝构造函数,形成无限递归。对于类类型,拷贝操作需要调用拷贝构造函数。

递归调用链:

  • 进入 Date(Date d) 时,需要先拷贝 d1d
  • 拷贝 d1d 又会调用 Date(Date d),无限循环。

在这里插入图片描述

代码示例:

class Date {
public:
    Date(const Date d)/*==Date d=d2*/ 
    {...}//会无穷递归
};

正确用法:

    //全缺省构造函数
    Date(int year = 0, int month = 1,int day=1){
        _year = year;
        _month = month;
        _day = day;
    }
    Date(Date& d){ //拷贝构造!Date& d=d2;
        //this指向调用者;例Date d2(d1),this指向调用者d2
        this->_year = d._year;
        this->_month = d._month;
        this->_day = d._day;
    }
main...
    Date d1(2025,5,12);
    //调用之前要先传参
    Date d2(d1);//拷贝构造d2;
    //和上面一样都是拷贝构造,两种写法,记住就行
    Date d3 = d1;

在这里插入图片描述
可知引用传参,别名指向同一个地址

在这里插入图片描述


05. 赋值运算符重载

5.1运算符重载

运算符重载允许用户自定义类对内置运算符,使得自定义类型能像内置类型一样进行运算。

**函数原型:**返回值类型operator操作符(参数列表)

  • 注意:
    • 只能重载C++已有的运算符,不能创建新运算符
    • 至少有一个操作数是类类型参数。
    • 不能改变运算符的优先级、结合性或操作数个数(如+始终是二元运算符)
    • :: .* ?: . sizeof 5个运算符不可重载
5.1.1运算符重载的两种形式

成员函数形式:

class Add {
public:
    Add(int x, int y) {}
    
    // 成员函数形式重载 +
    Add operator+(const Add& d2) const {//因为在class内部,this指针隐含了,指向被吊用的对象。在这个里面不能使用非成员函数形式会出现参数过多的报错!!!
        return Add(this->_x + d2.x, this->_y + d2.y);//this指针可不写
    }

private:
    int _x, _y;
};

// 使用
Add v1(1, 2), v2(3, 4);
 v1 + v2; // 等于 v1.operator+(v2)

非成员函数形式:

...private:
 int _year;
 int _month;
 int _day;
...
//在class外部
bool operator==(const Date& d1, const Date& d2){
    return d1._year == d2._year
  		  && d1._month == d2._month
       	   && d1._day == d2._day;
}
// 使用
d1==d2//等于operator==(d1,d2)

5.2 前置++和后置++

  • 前缀与后缀的区别
    • 前缀形式:ClassName& operator++()
    • 后缀形式:ClassName operator++(int)(参数int仅用于区分)
  • 示例
    class Sum {
    public:
        Sum() {}
        //  ++i,先加所以先自增,然后返回修改后的值
        Sum& operator++() {//this指向的对象函数结束后不会销毁,故以引用方式返回提高效率
            ++_num;
            return *this;
        }  
        // i++,先使用一个临时变量保存当前值并返回这个值,期间对_num值自增
        Sum operator++(int) {
            Sum temp = *this;
            ++_num;
            return temp;
        }
    private:
        int _num;
    };
    Counter c;
    Counter c1 = ++c; // 前置
    Counter c2 = c++; // 后置
    

5.3 赋值运算符重载

赋值运算符重载函数如果没有被显示定义,编译器会自动生成一个默认的赋值运算符重载,拷贝的方式是浅拷贝。与其他运算符重载函数不同的地方是赋值运算符重载必须定义成成员函数,不能定义成全局,如果定义成全局,类体里没有赋值运算符重载就会自动生成,这会与我们在全局定义的发生冲突。

class Date
{
public:
  Date(int year = 1900, int month = 1, int day = 1)
  {
    _year = year;
    _month = month;
    _day = day;
  }
    
  Date& operator=(const Date& d) //引用传参避免拷贝提高效率               
  {                              //引用返回因为赋值运算符支持连续赋值 d1 = d2 = d3;
    if (this != &d)
    {
      _year= d._year;
      _month = d._month;
      _day = d._day;
    }
    return *this;
  }
private:
  int _year;
  int _month;
  int _day;
};

06. 日期类实现

加速补齐实现中…

07. const成员修饰

const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。


08. &和const&操作符重载

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

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

相关文章

数据签名在区块链中的独特应用与挑战

随着信息技术的飞速发展,分布式系统因其高效、可靠、可扩展等显著优点,在众多领域得到了极为广泛的应用。分布式系统通过网络将多个独立的计算节点连接在一起,协同完成复杂的任务,这种架构使得系统具备了强大的容错能力和负载均衡…

数据可视化大屏——物流大数据服务平台(二)

代码分析: 物流大数据平台代码分析 这是一个基于 Bootstrap 和 ECharts 构建的物流大数据平台前端页面,设计采用了经典的三栏布局,主要展示河南省及全国的物流数据可视化内容。下面从多个维度进行分析: 1. 页面结构分析 整体采…

Maven 处理依赖冲突

Maven处理依赖冲突 什么是依赖冲突?如何解决?Maven自动处理依赖冲突的规则路径优先原则第一声明优先原则注意 子模块覆盖父模块父模块声明dependency子模块覆盖dependency父模块声明dependencyManagement 子模块覆盖dependency父模块声明dependencyManag…

5.12第四次作业

实验要求:完成上图内容,要求五台路由器的环回地址均可以相互访问 AR1 AR2 AR3 AR4 AR5 AS 200 ospf配置 AR2 AR3 AR4 BGP配置 AR1(AS100) AR2(AS200) AR4 AR5(AS300) 结果

【Lattice FPGA 开发】Diamond在线调试Reveal逻辑乱跳的解决

在Vivado中在always块中写逻辑时如果出现always块中的异步复位敏感词在块内部未使用的情况&#xff0c;如下例的rst&#xff1a; always (posedge clk or posedge rst) begin if(~tx_sense_flag)o_rd_adr < d1;else if((o_rd_adr d94) & (bit_cnt d7))o_rd_adr <…

Go语言——kratos微服务框架使用

文章目录 一、安装依赖二、创建项目三、初始化项目四、使用git_bash命令终端运行命令五、创建自己的项目1、修改app.proto3、internal/service/app.go4、修改internal/service/service.go文件5、创建internal/biz/content.go文件6、修改internal/biz/biz.go文件7、创建internal…

hiveserver2与beeline进行远程连接hive配置及遇到的问题

1、hiveserver2 参与用户模拟功能&#xff0c;因为开启后才能保证各用户之间的权限隔离。 1.1、配置 $HADOOP_HOME/etc/hadoop/core-site.xml <!--配置所有节点的root用户都可作为代理用户--> <property><name>hadoop.proxyuser.root.hosts</name>&…

Stable Diffusion进阶之Controlnet插件使用

前面已经对Stable Diffusion的文生图和图生图的操作界面做了详细的介绍&#xff0c;接下来会介绍Stable Diffusion的进阶部分Controlnet插件的使用。往期文章详见&#xff1a; 爆肝整理&#xff01;Stable Diffusion的完全使用手册&#xff08;一&#xff09;爆肝整理&#xff…

Multisim14使用教程详尽版--(2025最新版)

一、Multisim14前言 1.1、主流电路仿真软件 1. Multisim&#xff1a;NI开发的SPICE标准仿真工具&#xff0c;支持模拟/数字电路混合仿真&#xff0c;内置丰富的元件库和虚拟仪器&#xff08;示波器、频谱仪等&#xff09;&#xff0c;适合教学和竞赛设计。官网&#xff1a;艾…

使用Stable Diffusion(SD)中,步数(Steps)指的是什么?该如何使用?

Ⅰ定义&#xff1a; 在Stable Diffusion&#xff08;SD&#xff09;中&#xff0c;步数&#xff08;Steps&#xff09; 指的是采样过程中的迭代次数&#xff0c;也就是模型从纯噪声一步步“清晰化”图像的次数。你可以理解为模型在画这张图时“润色”的轮数。 Ⅱ步数的具体作…

【se-res模块学习】结合CIFAR-10分类任务学习

继CIFAR-10图像分类&#xff1a;【Res残差连接学习】结合CIFAR-10任务学习-CSDN博客 再优化 本次训练结果在测试集上的准确率表现可达到90%以上 1.训练模型&#xff08;MyModel.py&#xff09; import torch import torch.nn as nnclass SENet(nn.Module): # SE-Net模块def…

【C++设计模式之Template Method Pattern】

C设计模式之Template Method Pattern 模式定义核心思想动机(Motivation)结构&#xff08;Structure&#xff09;实现步骤应用场景要点总结 模式定义 模式定义&#xff1a; 定义一个操作中的算法的骨架(稳定)&#xff0c;而将一些步骤延迟(变化)到子类中。Template Method使得子…

英伟达Blackwell架构重构未来:AI算力革命背后的技术逻辑与产业变革

——从芯片暴力美学到分布式智能体网络&#xff0c;解析英伟达如何定义AI基础设施新范式 开篇&#xff1a;当算力成为“新石油”&#xff0c;英伟达的“炼油厂”如何升级&#xff1f; 2025年3月&#xff0c;英伟达GTC大会上&#xff0c;黄仁勋身披标志性皮衣&#xff0c;宣布了…

深度拆解!MES如何重构生产计划与排产调度全流程?

☂引言 在制造业数字化转型浪潮中&#xff0c;生产计划与排产调度的精准性直接决定企业竞争力。深蓝易网MES系统通过智能化调度与全流程管控&#xff0c;帮助企业破解排产难题&#xff0c;实现资源高效协同与生产透明化管理&#xff0c;为制造企业打造柔性化、敏捷化的生产体系…

信息系统项目管理师-软考高级(软考高项)​​​​​​​​​​​2025最新(十八)

个人笔记整理---仅供参考 第十八章项目绩效域 18.1干系人绩效域 18.2团队绩效域 18.3开发方法和生命周期绩效域 18.5项目工作绩效域 18.6交付绩效域 18.7度量绩效域 18.8不确定绩效域

UniDevTools - UniApp(前端app)调试工具使用

使用介绍 | UniDevTools 兼容框架&#xff1a; Vue2jsvuexVue3tsvuex(pinia)√√ 兼容平台&#xff1a; H5APP微信小程序APP-NVUE其他小程序UniAppX√√√√(大部分功能支持)未测试 (待办中) 下载安装 将下载好的源码解压至项目根目录&#xff0c;文件夹命名为 devTools …

spring中的@Lazy注解详解

一、核心功能与作用 Lazy 注解是 Spring 框架中用于延迟 Bean 初始化的核心工具&#xff0c;通过将 Bean 的创建推迟到首次使用时&#xff0c;优化资源利用和启动性能。其核心功能包括&#xff1a; 延迟初始化 默认情况下&#xff0c;Spring 在容器启动时立即初始化所有单例 …

视觉-语言-动作模型:概念、进展、应用与挑战(上)

25年5月来自 Cornell 大学、香港科大和希腊 U Peloponnese 的论文“Vision-Language-Action Models: Concepts, Progress, Applications and Challenges”。 视觉-语言-动作 (VLA) 模型标志着人工智能的变革性进步&#xff0c;旨在将感知、自然语言理解和具体动作统一在一个计…

语义分割模型部署到嵌入式终端的通用操作流程

以下是语义分割模型部署到嵌入式终端的通用操作流程&#xff0c;结合不同硬件平台&#xff08;如华为Atlas、地平线J5、树莓派等&#xff09;的共性需求整理而成&#xff1a; 一、环境准备与工具链配置 1. 嵌入式开发环境搭建 安装交叉编译工具链&#xff08;如ARM-GCC&…

R1-Searcher:用强化学习解锁大语言模型检索新能力!

R1-Searcher&#xff1a;用强化学习解锁大语言模型检索新能力&#xff01; 大语言模型&#xff08;LLMs&#xff09;发展迅猛&#xff0c;却常因依赖内部知识而在复杂问题上“栽跟头”。今天解读的论文提出R1-Searcher框架&#xff0c;通过强化学习提升LLMs检索能力。它表现超…