【C++】构造函数与析构函数
写在前面
构造函数与析构函数都是属于类的默认成员函数!
默认成员函数是程序猿不显示声明定义,编译器会中生成。
构造函数和析构函数的知识需要建立在有初步类与对象的基础之上的,关于类与对象不才在前面笔记中有详细的介绍:点我跳转
文章目录
- 写在前面
- 一、构造函数的特性
- 1.1、函数名与类名相同。
- 1.2、 无返回值。
- 1.3、 对象实例化时编译器自动调用对应的构造函数。
- 1.4、构造函数可以重载。
- 1.5、如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
- 1.6、无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
- 1.7、构造函数的初始化列表
- 二、析构函数
- 2.1、析构函数名是在类名前加上字符 ~
- 2.2、无参数无返回值类型
- 2.3、一个类只能有一个析构函数。
- 2.4、对象生命周期结束时,C++编译系统系统自动调用析构函数。
- 2.5、编译器生成的默认析构函数,对自定类型成员调用它的析构函数
- 2.6、如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数
一、构造函数的特性
构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象
其特征如下:
1.1、函数名与类名相同。
1.2、 无返回值。
1.3、 对象实例化时编译器自动调用对应的构造函数。
class stack {
public:stack() {//构造函数cout << "this is stack()" << endl;}void Init(int defintCapacity) {_arr = (int*)calloc(defintCapacity, sizeof(int));if (nullptr == _arr){perror("malloc申请空间失败");return;}_capacity = defintCapacity;_size = 0;}void push(int x) {//....扩容等_arr[_size++] = x;}
private:int* _arr;int _size;int _capacity;
};int main() {stack s1;return 0;
}
程序运行结果:
- 在上述代码中,不才创建了一个默认构造函数
stack
,在构造函数中,我们只让其打印字符串this is stack()
,之后,我们在s1
对象中,并没有显示的调用构造函数,但是字符串就被打印出来了,这就说明的对象实例化时编译器自动调用对应的构造函数
这时候,我们就可以把stack
的初始化函数设置放入构造函数中,每当我们创建一个对象时,通过构造函数自动初始化数据。如下:
class stack {
public:stack(int defintCapacity = 4) {_arr = (int*)calloc(defintCapacity, sizeof(int));if (nullptr == _arr){perror("malloc申请空间失败");return;}_capacity = defintCapacity;_size = 0;}void push(int x) {//....扩容等_arr[_size++] = x;}
private:int* _arr;int _size;int _capacity;
};int main() {stack s1;return 0;
}
运行结果:
- 这时候,我们就不用每次都显示的初始化数据了,而且也不怕忘记初始化。
1.4、构造函数可以重载。
构造函数也是函数,是函数就可以重载
class stack {
public:stack(int defintCapacity = 4) {_arr = (int*)calloc(defintCapacity, sizeof(int));if (nullptr == _arr){perror("malloc申请空间失败");return;}_capacity = defintCapacity;_size = 0;}stack(int* arr, int defintCapacity) {if (nullptr == arr) {perror("malloc申请空间失败");return;}_arr = arr;_capacity = defintCapacity;_size = 0;}void push(int x) {//....扩容等_arr[_size++] = x;}
private:int* _arr;int _size;int _capacity;
};int main() {int* arr = (int*)calloc(2, sizeof(int));stack s1(arr, 2);return 0;
}
程序运行结果:
和函数重载一样的逻辑,编译器会根据符号名去调用对应的构造函数。
需要注意,调用默认构造函数不需要加括号,因为加上括号后,编译器会认为是函数
举个栗子:
stack s1
:这时s1
代表的是调用stack
的默认构造函数的对象
stack s1()
:这时s1
就被当做,返回值是stack
类且没有形参的函数。
有参调用就和普通函数一样,只不过是对象+参数列表stack s1(arr, 2)
1.5、如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
默认构造函数在C++中有特殊定义,在C++标准中,默认构造函数不会对内置类型
进行处理,自定义类型
会调用它的默认构造函数。但是现在有些编译器会对内置类型
进行初始化,但这是该编译器自己的行为,C++标准中是不进行处理的。
内置类型/基本类型:语言本身定义的基础类型(如int
、char
、指针、double
等)
自定义类型:使用class
、struct
等定义的类型
class stack {
public:stack(int defintCapacity = 4) {_arr = (int*)calloc(defintCapacity, sizeof(int));if (nullptr == _arr){perror("malloc申请空间失败");return;}_capacity = defintCapacity;_size = 0;}stack(int* arr, int defintCapacity) {if (nullptr == arr) {perror("malloc申请空间失败");return;}_arr = arr;_capacity = defintCapacity;_size = 0;}void push(int x) {//....扩容等_arr[_size++] = x;}
private:int* _arr;int _size;int _capacity;
};class Date
{
public:void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private:int _year;int _month;int _day;
};
int main() {Date d1;return 0;
}
程序运行结果:(在vs2022环境下)
在默认构造函数中,并不会对定义类型进行任何操作,貌似不能证明默认构造函数的存在,但是我们把Date
类设置为,下程序时:
class stack {
public:stack(int defintCapacity = 4) {_arr = (int*)calloc(defintCapacity, sizeof(int));if (nullptr == _arr){perror("malloc申请空间失败");return;}_capacity = defintCapacity;_size = 0;}stack(int* arr, int defintCapacity) {if (nullptr == arr) {perror("malloc申请空间失败");return;}_arr = arr;_capacity = defintCapacity;_size = 0;}void push(int x) {//....扩容等_arr[_size++] = x;}
private:int* _arr;int _size;int _capacity;
};class Date
{
public:void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private://内置类型int _year;int _month;int _day;//自定义类型stack _st;
};int main() {Date d1;return 0;
}
运行结果:(在VS2013编译器中)
- 在vs2013中,我们可以清晰看出内置类型是不会进行处理的,而自定义类型是会调用其默认构造函数
但是我们在VS2022中尝试一下
- 我们发现在vs2022编译环境下,有自定义类型情况中,内置类型会被初始化为0,在上例中,我们也发现,在没有自定义类型情况中,内置类型是不会处理的
所以,不才推荐在C++中类中,我们默认内置类型是未被处理的,自定义类型是会调用其默认构造函数的,这样不会出现程序运行错误。
在
C++11
后,对成员变量
做了一个补丁,可以在声明成员变量
时给定一个缺省值。
这里不才以内置类型为例,
class Date
{
public:Date(){}Date(int year, int month, int day) {_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private://内置类型 //这里不是初始化,而是声明//这里给的是默认缺省值,给编译器生成默认构造函数时使用int _year = 1;int _month = 1;int _day = 1;};int main() {Date d1;d1.Print();return 0;
}
程序运行结果:
如果我们调用默认构造函数,那么内置类型的值就是程序猿给定的缺省值。如果我们调用不是默认构造函数,那么使用的就是自定义构造函数的值,如下图。
什么情况下可以直接使用默认构造函数:
- 内置类型成员都有缺省值,且初始化符合要求
- 全部都是自定义类型成员,且这些类型都定义了默认构造函数。
1.6、无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。
虽然在语法中,无参的构造函数和全缺省的构造函数形参了函数重载,编译不会有错,但是在对象初始化时,无参调用存在歧义。
class Date
{
public:Date() {}Date(int year = 2035, int month = 1, int day = 1) {_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private:int _year = 1;int _month = 1;int _day = 1;};int main() {Date d1;d1.Print();return 0;
}
程序运行结果:
- 无参构造函数和全缺省的构造函数都是不需要传参调用的,所以在函数调用时,就会报错
对重载函数的调用不明确
无参构造函数
、全缺省构造函数
、我们没写编译器默认生成的构造函数
,只要不传参就可以调用的,都可以认为是默认构造函数,而默认构造函数只能存在一个!
1.7、构造函数的初始化列表
构造函数体赋值
在上述的构造器中,我们构造函数内进行的操作是构造函数体赋值,这些操作只是赋值,并不是属性的初始化定义。如下
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
_year = year;
、_month = month;
、_day = day;
这些在构造器中只是充当赋值的作用,并不是对属性_year
、_month
、_day
的初始化定义。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
初始化列表:把类中的所有属性进行初始化定义。
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个 “成员变量” 后面跟一个放在括号中的初始值或表达式。如下代码
class Date
{
public:Date(int year, int month, int day):_year(year),_month(month),_day(day)//,_day(day) err:最多只能出现一次{}
private:int _year;int _month;int _day;
};
- 每个成员变量在初始化列表中最多只能出现一次(初始化只能初始化一次)
- 类中包含以下成员,必须放在初始化列表位置进行初始化:
- 引用成员变量
const
成员变量- 自定义类型成员(且该类没有默认构造函数时)
因为引用成员变量和 const
成员变量在初始化时,必须要进行赋值。而自定义类型成员。构造函数编译器只会调用自定义类型的默认构造函数,如果没有默认构造函数的情况编译器就无法找到自定义类型所对应的构造函数。
引用成员变量和 const
成员变量 不在初始化列表进行初始化。而在构造函数体赋值中进行赋值来达到初始化。
自定义类型在没有默认构造函数的情况下,让编译器自己去寻找默认构造函数。
所以我们就必须在属性初始化的时候赋初值。如下代码:
class A {
public:A(int a):_a(a){ }
private:int _a = 0;
};class Date
{
public:Date(int year, int month, int day):_year(year),_month(month),aa(10){}
private:A aa;const int _year;int& _month;int _day;
};
尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。 对于内置类型也是在初始化列表中进行初始化。
我们属性都是在初始化列表中进行初始化。构造函数体赋值一般是完成初始化列表不能完成的工作。如检查动态开辟内存是否为空等操作。
class stack {
public:stack(int size):_arr( (int*)malloc(sizeof(int) * size) ),_capacity(0),_size(size){//检查_arr动态开辟的空间是否为空if (_arr == nullptr) {perror("malloc::>");exit(1);}//再把_arr初始化为0memset(_arr, 0, (sizeof(int) * size) );}private:int* _arr;int _capacity;int _size;
};int main() {stack s1(10);return 0;
}
成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
在上述的stack
类中,很多小伙伴在动态开辟_arr
的初始化时,先在初始化列表时把_size
放在了_arr
的前面,之后把_arr
计算空间大小的size
使用了属性的_size
这样导致的程序崩溃
class stack {
public:stack(int size): _capacity(0), _size(size),_arr( (int*)malloc(sizeof(int) * _size) ){//检查_arr动态开辟的空间是否为空if (_arr == nullptr) {perror("malloc::>");exit(1);}//再把_arr初始化为0memset(_arr, 0, (sizeof(int) * size) );}private:int* _arr;int _capacity;int _size;
};int main() {stack s1(10);return 0;
}
- 这时候初始化顺序是先初始化
_arr
数组,此时_size
并没有被初始化,那么这时候_size
就是一个随机值。 - 我们使用一个巨大的随机值去动态开辟一个空间,那么动态开辟出来的空间也是一个巨大的空间,所以程序会崩溃。
- 只有初始化完了
_arr
数组,再初始化_capacity
,最后初始化_size
。
为了深刻理解:我们再举个栗子,下面程序运行结果是什么。
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(20);aa.Print();
}
- 根据我们理解的:成员变量在类中声明次序就是其在初始化列表中的初始化顺序,此时程序的运行结果为:
20
随机值
不才这里建议:声明的顺序与初始化列表顺序保持一致
二、析构函数
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
析构函数是特殊的成员函数,其特征如下:
2.1、析构函数名是在类名前加上字符 ~
2.2、无参数无返回值类型
2.3、一个类只能有一个析构函数。
若未显式定义,系统会自动生成默认的析构函数。注意:析构函数没有形参所以不能重载
2.4、对象生命周期结束时,C++编译系统系统自动调用析构函数。
class Date
{
public:Date() {cout << "Date()" << endl;}Date(int year, int month, int day) {_year = year;_month = month;_day = day;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}~Date() {cout << "~Date()" << endl;}private:int _year = 1;int _month = 1;int _day = 1;};int main() {Date d1;{//创建了代码块用于验证:对象生命周期结束时,C++编译系统系统是否会自动调用析构函数Date d2;d2.Print();printf("\n");cout << &d2 << endl;}printf("\n");d1.Print();return 0;
}
程序运行结果:
2.5、编译器生成的默认析构函数,对自定类型成员调用它的析构函数
class stack {
public:stack(int defintCapacity = 4) {_arr = (int*)calloc(defintCapacity, sizeof(int));if (nullptr == _arr){perror("malloc申请空间失败");return;}_capacity = defintCapacity;_size = 0;cout << "stack()" << endl;}stack(int* arr, int defintCapacity) {if (nullptr == arr) {perror("malloc申请空间失败");return;}_arr = arr;_capacity = defintCapacity;_size = 0;}void push(int x) {//....扩容等_arr[_size++] = x;}~stack() {free(_arr);_arr = nullptr;cout << "~stack()" << endl;}
private:int* _arr;int _size;int _capacity;
};class Date
{
public:Date() {cout << "Date()" << endl;}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}private://内置类型 给定缺省值int _year = 1;int _month = 1;int _day = 1;//自定义类型stack _st;
};int main() {Date d1;d1.Print();return 0;
}
程序运行结果:
main
方法中创建了Date
对象d1
,而d1
中包含4个成员变量,其中_year
,_month
,_day
三个是内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可。- 但是
_st
是stack
类的对象,所以在d1
销毁时,要将其内部包含的stack
类的_st
对象销毁,所以要调用stack
类的析构函数。 main
函数中不能直接调用stack
类的析构函数,实际要释放的是Date
类对象,所以编译器会调用Date
类的析构函数,而Date
没有显式提供,则编译器会给Date
类生成一个默认的析构函数,目的是在其内部调用stack
类的析构函数,即当Date
对象销毁时,要保证其内部每个自定义对象都可以正确销毁
2.6、如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数
析构函数的使用:
- 一般情况下,有动态申请资源 ,就需要显示写析构函数释放资源
- 没有动态申请资源,不需要写析构函数
- 需要释放资源的类型都是自定义类型,在该类中就不需要写析构函数。因为默认生成的析构函数遇到自定义类型会自动调用自定义类型的析构函数
- 特殊场景特殊使用
以上就是本章所有内容。若有勘误请私信不才。万分感激💖💖 如果对大家有用的话,就请多多为我点赞收藏吧~~~💖💖
ps:表情包来自网络,侵删🌹
相关文章:

【C++】构造函数与析构函数
写在前面 构造函数与析构函数都是属于类的默认成员函数! 默认成员函数是程序猿不显示声明定义,编译器会中生成。 构造函数和析构函数的知识需要建立在有初步类与对象的基础之上的,关于类与对象不才在前面笔记中有详细的介绍:点我…...
Agent区别于MOE和RAG的核心; Agent(智能体)、RAG和MOE区别
Agent区别于MOE(专家混合模型)和RAG(检索增强生成)的核心 目录 Agent区别于MOE(专家混合模型)和RAG(检索增强生成)的核心自主性与决策能力环境交互与学习能力多模态感知与处理能力Agent(智能体)、RAG(检索增强生成)和MOE(专家混合模型)区别Agent(智能体)RAG(检…...

【PCL】Segmentation 模块—— 欧几里得聚类提取(Euclidean Cluster Extraction)
1、简介 PCL 的 Euclidean Cluster Extraction(欧几里得聚类提取) 是一种基于欧几里得距离的点云聚类算法。它的目标是将点云数据分割成多个独立的簇(clusters),每个簇代表一个独立的物体或结构。该算法通过计算点与点…...

LuaJIT Garbage Collector Algorithms
Explain 本篇文章是对Make Pall发表wili内容《LuaJIT 3.0 new Garbage Collector》的翻译和扩展,因为原文是对LuaJIT 2.x GC重要功能的简介和对LuaJIT 3.0 new GC的工作计划,所以它并不是系统性介绍GC的文章。希望以后能有精力系统性的对LuaJIT 2.x GC做…...
go采集注册表
package mainimport ("fmt""golang.org/x/sys/windows/registry""log""os""strconv""strings" )func USBSTOR_Enum() {// 打开注册表键keyPath : SYSTEM\CurrentControlSet\Services\USBSTOR\Enumk, err : regist…...
软件工程师欧以宁:引领无人机导航与物联网安全的技术革新
在科技日新月异的今天,软件工程师欧以宁凭借卓越的技术能力和前瞻性的创新思维,成为了无人机自主导航和物联网安全领域的佼佼者。作为一名深耕技术前沿的专家,欧以宁不仅推动了无人机导航技术的突破性进展,还为智能家居和物联网的安全架构提供了全新的解决方案。她的研究成果,以…...

从零开始:Gitee 仓库创建与 Git 配置指南
引言 Git 是一款广泛使用的版本控制工具,它能够帮助开发者在开发过程中高效地管理代码的版本。而 Gitee(码云)是国内知名的 Git 托管平台,它提供了强大的代码托管、团队协作和项目管理功能。如果你是 Git 和 Gitee 的新手&#x…...

浅谈计算机网络02 | SDN控制平面
计算机网络控制平面 一、现代计算机网络控制平面概述1.1 与数据平面、管理平面的关系1.2 控制平面的发展历程 二、控制平面的关键技术剖析2.1 网络层协议2.1.1 OSPF协议2.1.2 BGP协议 2.2 SDN控制平面技术2.2.1 SDN架构与原理2.2.2 OpenFlow协议2.2.3 SDN控制器 一、现代计算机…...

在 QNAP NAS中使用 Container Station 运行 Docker 的完整指南
QNAP 为用户提供了一个名为 Container Station 的应用,它在 QNAP NAS 上将 Docker 和 LXC 结合在一起,通过图形化界面,让用户更轻松地在 NAS 上管理容器。本文将带你一步步了解如何在 QNAP NAS 上安装和使用 Container Station,以…...

XML在线格式化 - 加菲工具
XML在线格式化 打开网站 加菲工具 选择“XML 在线格式化” 输入XML,点击左上角的“格式化”按钮 得到格式化后的结果...
大数据学习(34)-mapreduce详解
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦ᾑ…...
代码合并冲突解决push不上去的问题
环境:【IntelliJ IDEA】 【Gerrit】 1、错误信息 代码合并,迭代1合并到迭代2,解决冲突后,依然push不上去,报错信息如下: remote: Processing changes: refs: 1 remote: Processing changes: refs…...

万字长文介绍ARINC 653,以及在综合模块化航空电子设备(IMA)中的作用
文章目录 一、引言二、ARINC 653背景三、整体系统架构四、应用/执行(APEX)接口五、ARINC 653 RTOS内部机制六、健康监测功能七、软件应用八、ARINC 653现状九、总结 一、引言 在现代航空领域,综合模块化航空电子设备(IMA…...
MySQL 与 Redis 数据一致性 2
1. 强一致还是最终一致?2. 先写 MySQL 还是先写Redis?case 1 3. 缓存(Redis)更新还是清除?更新策略更新策略会有数据不一致问题?数据不一致的概率与影响如果使用监听binlog更新数据还会出现数据不一致问题?binlog的消费问题 使用消息队列行不行?其他方案总结: 数据不一致…...
MySQL程序之:使用类似URI的字符串或键值对连接到服务器
本节介绍使用类似URI的连接字符串或键值对来指定如何为MySQLShell等客户端建立到MySQL服务器的连接。 以下MySQL客户端支持使用类似URI的连接字符串或键值对连接到MySQL服务器: MySQL Shell实现X DevAPI的MySQL连接器 本节记录了所有有效的类似URI的字符串和键值…...

Docker私有仓库管理工具Registry
Docker私有仓库管理工具Registry 1 介绍 Registry是私有Docker仓库管理工具,Registry没有可视化管理页面和完备的管理策略。可借助Harbor、docker-registry-browser完成可视化和管理。Harbor是由VMware开发的企业级Docker registry服务。docker-registry-browser是…...

若依前后端分离项目部署(使用docker)
文章目录 一、搭建后端1.1 搭建流程:1.2 后端零件:1.2.1 mysql容器创建:1.2.2 redis容器创建:1.2.3 Dockerfile内容:1.2.4 构建项目镜像:1.2.5 创建后端容器: 二、前端搭建:2.1 搭建流程&#x…...

Unity2021.3.13崩溃的一种情况
如果出现如下的报错,可能是软件冲突的原因。自己的原因是使用f.lux这款软件似乎和Unity相互冲突,出现下面报错。 错误信息如上图...

Temp123
MapDB:的持久化机制,以及源码分析和摘取 1、spark streaming--struct streaming 基于 时间间隔 攒批 2、kafka-connect-hdfs 控制 flush.size 和 interval.ms控制 攒批 - 完全自研 攒批机制 - 使用 embeded 版 https://lxblog.com/qianwen/share?shar…...

春秋杯-WEB
SSTI 可以看到主页那里有个登录测试之后为ssti {{4*4}} fenjing梭哈即可得到payload {{((g.pop.__globals__.__builtins__.__import__(os)).popen(cat flag)).read()}}file_copy 看到题目名字为file_copy, 当输入路径时会返回目标文件的大小, 通…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...