CPP从入门到入土之类和对象Ⅱ

ops/2025/4/2 5:07:18/

一、六大默认成员函数

默认成员函数是用户没有显式实现,编译器自动生成的成员函数。
一个类,我们在不写的情况下,编译器会默认生成六个默认成员函数
在这里插入图片描述
本文详细介绍构造函数和析构函数

二、构造函数

构造函数虽名为构造函数,但是这个函数并不开辟空间创建对象(经常使用的局部对象是栈帧创建的)
构造函数的功能是:在对象实例化时初始化对象,类似于我们以前写的Init()函数
CPP引入构造函数,我们也就可以代替Init()函数了

构造函数的特点:

  • 函数值与类名相同
class Info{
public:
// 构造函数Info(){//...}
private:
//...
};
  • 无返回值(啥都不需要给,void也不用)
  • 对象实例化时(创建对象)系统会自动调用对应的构造函数
  • 支持重载,可以根据参数不同定义多个构造函数
  • 如果没有显式定义构造函数,CPP的编译器会自动生成一个无参的默认构造函数,一旦显式定义就不会生成

构造函数的类型

  1. 默认构造函数
    默认构造函数分为无参构造函数编译器自动生成的构造函数全缺省构造函数
    这三个函数有且只能存在一个:
    在这里插入图片描述

无参构造函数和 全缺省构造函数虽能构成函数重载,但是会产生调用歧义
总结一下: 默认构造函数是不用传实参的构造函数

class Info {
public:// 无参的默认构造函数Info() {_name = "UnKnow";_age = 0;}void Print() {cout << " 默认构造函数被调用" << endl;cout << _name << "  " << _age << endl;}
private:string _name;int _age;
};int main() {Info I1;I1.Print();
}

在这里插入图片描述

  1. 带参数的构造函数
class Info {
public:// 带参的构造函数Info(string name, int age) {_name = name;_age = age;}void Print() {cout << " 默认构造函数被调用" << endl;cout << _name << "  " << _age << endl;}
private:string _name;int _age;
};int main() {// 调用带参数的构造函数Info I2("kunkun", 18);I2.Print();
}

在这里插入图片描述

编译器自动生成的默认构造函数深度剖析

我们如果没有显式定义构造函数,编译器自动生成的构造函数会将对象初始化成什么呢?
类型的分类:
在这里插入图片描述

  • 内置类型:没有规定要处理(可处理可不处理,看编译器类型)
    在这里插入图片描述

  • 自定义类型:调用自定义类型对象的默认构造函数,本质是不断套娃,深挖!!!

在这里插入图片描述
分析一下:

D1这个对象中有三个内置类型成员变量和一个自定义类型成员变量,不写构造函数,首先自动生成Date()的默认构造函数,到private中发现三个内置类型,则不做处理,有个自定义类型_t,则去调用Time()的构造函数,发现有构造函数,则按照构造函数初始化命令初始化,如果Time()没有构造函数呢?那么_hour _minute _second也是内置类型,不做处理

在这里插入图片描述
注意:没有默认构造函数会报错
在这里插入图片描述

三、析构函数

析构函数构造函数功能相反,析构函数不是销毁对象,比如局部对象存在栈中,函数栈帧结束就自动销毁释放内存。
析构函数的功能是在对象销毁时完成对象中资源的清理释放
析构函数的功能类似于Destroy(),析构函数就可以完美替代Destroy()

析构函数的特点

  • 无参数无返回值,与构造函数类似
  • 函数名与类名相同,在类名前加字符 “~” eg:Name()
  • 一个类只能有一个析构函数,所以析构函数不能重载如果没有显式定义,系统会自动生成默认的析构函数
  • 对象生命周期结束,会自动调用析构函数
  • 与构造函数相同,编译器自动生成的析构函数对内置类型不做处理,对自定义类型则会调用它的析构函数
    注意:我们显式写析构函数,自定义类型成员会调用它的析构函数,换句话说,自定义类型成员无论什么情况下都会调用析构函数

析构函数的语法

class Test {
public:Test() {cout << "构造函数调用成功" << endl;}~Test() {cout << "析构函数调用成功" << endl;}
private:
};int main() {cout << "程序开始运行" << endl;{Test T;// 构造函数被调用}// T生命周期结束cout << "程序运行结束";
}

在这里插入图片描述
总结:

  • 有资源需要手动清理,需要写析构函数
  • 有两种场景不需要写析构函数,利用默认生成的即可:
    1. 没有资源需要清理,例如:Date()日期列表全是局部成员
    2. 内置类型没有资源需要清理,剩下的全是自定义类型成员,且这些类有正确的析构函数 eg:
public:Engine() { std::cout << "Engine created.\n"; }~Engine() { std::cout << "Engine destroyed.\n"; }
};class Car {
public:Engine engine;int speed;
}; // Car的析构函数不需要手写

http://www.ppmy.cn/ops/167518.html

相关文章

一个简单C程序

基本示例&#xff0c; 这里有一个经典的“Hello, World!”程序供参考&#xff1a; c #include <stdio.h> int main() { printf("Hello, World!\n"); return 0; } 现在来分析一下上面的实例程序。 1. #include 指令 实例代码中的第一行&#xff1a; #incl…

Oracle OCP认证没落了吗?

Oracle OCP认证没落了吗? Oracle的OCP认证是数据库领域必考的一个认证&#xff0c;但随着国产化的发展&#xff0c;国内很多企业开发了自己的数据库产品&#xff0c;这种情况对很多人造成了错误的认识&#xff1a;OCP被淘汰了吗?不然&#xff0c;从行业需求、技术趋势、认证体…

【程序人生】成功人生架构图(分层模型)

文章目录 ⭐前言⭐一、根基层——价值观与使命⭐二、支柱层——健康与能量⭐三、驱动层——学习与进化⭐四、网络层——关系系统⭐五、目标层——成就与财富⭐六、顶层——意义与传承⭐外层&#xff1a;调节环——平衡与抗风险⭐思维导图 标题详情作者JosieBook头衔CSDN博客专家…

鸿蒙app 开发中 如何 自己定义 选中图库照片或者视频的逻辑

使用找个组件 可以 自己书写 选中照片或者视频的逻辑

大语言模型的长思维链推理:综述(下)

25年3月来自哈工大、中南大学、香港大学和复旦大学的论文“Towards Reasoning Era: A Survey of Long Chain-of-Thought for Reasoning Large Language Models”。 OpenAI-O1 和 DeepSeek-R1 等推理大语言模型 (RLLM) 领域的最新进展&#xff0c;已在数学和编码等复杂领域展示…

联核科技AGV无人叉车有哪些常见的安全防护措施?

联核科技的AGV无人自动化叉车作为自动化设备&#xff0c;它的安全防护措施通常涵盖多个层面&#xff0c;以确保在复杂环境中安全运行。以下是联核AGV无人叉车常见的安全防护措施及技术实现方式&#xff1a;联核科技官网-AGV叉车十大品牌-无人叉车厂家-自动化叉车-智能搬运码垛机…

数组模拟邻接表 #图论

文章目录 为什么要用数组来模拟邻接表存储思路遍历思路 树是特殊的图&#xff0c;因此邻接表可以存储图和树两种数据结构。 为什么要用数组来模拟邻接表 在算法设计当中&#xff0c;利用数组来代替结构体模拟各种数据结构会更加简单。 存储思路 给定如下数据,我们可以构造如…

【cuda学习日记】8.2 GPU加速库 --cuBLAS

8.2.1 cuBLAS cuBLAS是一个线性代数子程式&#xff0c;基于BLAS basic linear algebra subprograms&#xff09;&#xff0c;即基本线性代数子程序。cuBLAS不支持多种稀疏数据格式&#xff0c;它仅支持并善于优化稠密向量和稠密矩阵的操作。 由于最初的BLAS库是用FORTRAN语言…