当前位置: 首页 > news >正文

【C++】5.类和对象(3)

文章目录

  • 3.析构函数
    • 析构函数的特点:
  • 4.拷贝构造函数
    • 拷贝构造的特点:


3.析构函数

析构函数与构造函数功能相反,析构函数不是完成对对象本身的销毁,比如局部对象是存在栈帧的,函数结束栈帧销毁,他就释放了,不需要我们管,C++规定对象在销毁时会自动调用析构函数,完成对象中资源的清理释放工作。析构函数的功能类比我们之前Stack实现的Destroy功能,而像Date没有Destroy,其实就是没有资源需要释放,所以严格说Date是不需要析构函数的。

析构函数的特点:

  1. 析构函数名是在类名前加上字符 ~
  2. 无参数无返回值。 (这里跟构造类似,也不需要加void)
  3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。
  4. 对象生命周期结束时,系统会自动调用析构函数。
  5. 跟构造函数类似,我们不写编译器自动生成的析构函数对内置类型成员不做处理,自定类型成员会调用他的析构函数。
  6. 还需要注意的是我们显示写析构函数,对于自定义类型成员也会调用他的析构,也就是说自定义类型成员无论什么情况都会自动调用析构函数。
  7. 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,如Date;如果默认生成的析构就可以用,也就不需要显示写析构,如MyQueue;但是有资源申请时,一定要自己写析构,否则会造成资源泄漏,如Stack
  8. 一个局部域的多个对象,C++规定后定义的先析构。
#include<iostream>
using namespace std;
typedef int STDataType;
class Stack
{public:Stack(int n = 4){_a = (STDataType*)malloc(sizeof(STDataType) * n);if (nullptr == _a){perror("malloc申请空间失败");return;}_capacity = n;_top = 0;}~Stack(){cout << "~Stack()" << endl;free(_a);_a = nullptr;_top = _capacity = 0;}private:STDataType* _a;size_t _capacity;size_t _top;
};
// 两个Stack实现队列
class MyQueue
{public://编译器默认生成MyQueue的析构函数调用了Stack的析构,释放的Stack内部的资源// 显示写析构,也会自动调用Stack的析构/*~MyQueue(){}*/private:Stack pushst;Stack popst;
};
int main()
{Stack st;MyQueue mq;return 0;
}

对比一下用C++C实现的Stack解决之前括号匹配问题isValid,我们发现有了构造函数和析构函数确实方便了很多,不会再忘记调用InitDestory函数了,也方便了不少。

#include<iostream>
using namespace std;
// 用最新加了构造和析构的C++版本Stack实现
bool isValid(const char* s) {Stack st;while (*s){if (*s == '[' || *s == '(' || *s == '{'){st.Push(*s);}else{// 右括号比左括号多,数量匹配问题if (st.Empty()){return false;}// 栈里面取左括号char top = st.Top();st.Pop();// 顺序不匹配if ((*s == ']' && top != '[')|| (*s == '}' && top != '{')|| (*s == ')' && top != '(')){return false;}}++s;}// 栈为空,返回真,说明数量都匹配 左括号多,右括号少匹配问题return st.Empty();
}
// 用之前C版本Stack实现
bool isValid(const char* s) {ST st;STInit(&st);while (*s){// 左括号入栈if (*s == '(' || *s == '[' || *s == '{'){STPush(&st, *s);}else // 右括号取栈顶左括号尝试匹配{if (STEmpty(&st)){STDestroy(&st);return false;}char top = STTop(&st);STPop(&st);// 不匹配if ((top == '(' && *s != ')')|| (top == '{' && *s != '}')|| (top == '[' && *s != ']')){STDestroy(&st);return false;}}++s;}// 栈不为空,说明左括号比右括号多,数量不匹配bool ret = STEmpty(&st);STDestroy(&st);return ret;
}
int main()
{cout << isValid("[()][]") << endl;cout << isValid("[(])[]") << endl;return 0;
}
/*
关于编译器自动生成的析构函数,是否会完成一些事情呢?下面的程序我们会看到,编译器
生成的默认析构函数,对自定类型成员调用它的析构函数。
*/
class Time
{
public:~Time(){cout << "~Time()" << endl;}
private:int _hour;int _minute;int _second;
};class Date
{
private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t;
};
int main()
{Date d;return 0;
}/*程序运行结束后输出:~Time()在main方法中根本没有直接创建Time类的对象,为什么最后会调用Time类的析构函数?因为:main方法中创建了Date对象d,而d中包含4个成员变量,其中_year, _month, _day三个是内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可;而_t是Time类对象,所以在d销毁时,要将其内部包含的Time类的_t对象销毁,所以要调用Time类的析构函数。但是:main函数中不能直接调用Time类的析构函数,实际要释放的是Date类对象,所以编译器会调用Date类的析构函数,而Date没有显式提供,则编译器会给Date类生成一个默认的析构函数,目的是在其内部调用Time类的析构函数,即当Date对象销毁时,要保证其内部每个自定义对象都可以正确销毁main函数中并没有直接调用Time类析构函数,而是显式调用编译器为Date类生成的默认析构函数注意:创建哪个类的对象则调用该类的析构函数,销毁那个类的对象则调用该类的析构函数
*//*
如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如Date类;
有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类。
*/

注意:

  1. 一般情况下,有动态申请的资源,就需要显示所写的析构函数,来释放资源。

    例如:栈需要写析构

  2. 没有动态申请的资源,不需要写析构函数。因为没有资源需要释放。

    例如:

    class Data{
    private:int _year;int _month;int _day;int _arr[100];
    };
    
  3. 需要释放资源的成员都是自定义类型,不需要写析构函数。

    例如:

    class MyQue{
    private:Stack _pushst;Stack _popst;
    };
    

因为默认生成的构造会自动调用默认构造函数

默认生成的析构会自动调用默认析构函数


4.拷贝构造函数

如果一个构造函数的第一个参数是自身类类型的引用,且任何额外的参数都有默认值,则此构造函数也叫做拷贝构造函数,也就是说拷贝构造是一个特殊的构造函数。

拷贝构造的特点:

  1. 拷贝构造函数是构造函数的一个重载。
  2. 拷贝构造函数的第一个参数必须是类类型对象的引用,使用传值方式编译器直接报错,因为语法逻辑上会引发无穷递归调用。 拷贝构造函数也可以多个参数,但是第一个参数必须是类类型对象的引用,后面的参数必须有缺省值。
  3. C++规定自定义类型对象进行拷贝行为必须调用拷贝构造,所以这里自定义类型传值传参和传值返回都会调用拷贝构造完成。
  4. 若未显式定义拷贝构造,编译器会生成自动生成拷贝构造函数。自动生成的拷贝构造对内置类型成员变量会完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用他的拷贝构造。
  5. Date这样的类成员变量全是内置类型且没有指向什么资源,编译器自动生成的拷贝构造就可以完成需要的拷贝,所以不需要我们显示实现拷贝构造。像Stack这样的类,虽然也都是内置类型,但是_a指向了资源,编译器自动生成的拷贝构造完成的值拷贝/浅拷贝不符合我们的需求,所以需要我们自己实现深拷贝(对指向的资源也进行拷贝)。像MyQueue这样的类型内部主要是自定义类型Stack成员,编译器自动生成的拷贝构造会调用Stack的拷贝构造,也不需要我们显示实现MyQueue的拷贝构造。这里还有一个小技巧,如果一个类显示实现了析构并释放资源,那么他就需要显示写拷贝构造,否则就不需要。
  6. 传值返回会产生一个临时对象调用拷贝构造,传值引用返回,返回的是返回对象的别名(引用),没有产生拷贝。但是如果返回对象是一个当前函数局部域的局部对象,函数结束就销毁了,那么使用引用返回是有问题的,这时的引用相当于一个野引用,类似一个野指针一样。传引用返回可以减少拷贝,但是一定要确保返回对象,在当前函数结束后还在,才能用引用返回。
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// d2(d1)//Date(Date& d);// 正确写法//拷贝构造函数Date(const Date& d){cout << "Date(Date& d)" << endl;//注意:_year = d._year;这个里面的_year不是private:里面的int _year;//_year = d._year;这个左边的_year是d2的_year,也就是this->_year,因为this指针是d2,也就是d2传给了this//右边的d._year是d,也就是d1的_year_year = d._year;_month = d._month;_day = d._day;/*d._year = _year;d._month = _month;d._day = _day;*/}
private:int _year;int _month;int _day;
};class MyQueue
{
private:/*Stack _pushst;Stack _popst;*/
};void func(int i){}void func(Date d) {}int main()
{// 可以不写,默认生成的拷贝构造就可以用Date d1(2023, 4, 25);Date d2(d1);//Data(Data& d)里面的d是d1的别名//this指针是d2,也就是d2传给了this//内置类型直接拷贝,void func(int i);//直接把4个字节的10拷贝给ifunc(10);//自定义类型的拷贝,规定了要定义拷贝构造去拷贝//void func(Date d){}会先调用Date(const Date& d);然后进入void func(Date d) //如果Date(const Date& d);改成了Date(Date d);那么就会出现无限递归,编译器会报错func(d1);// 必须自己实现,实现深拷贝/*Stack st1;Stack st2(st1);*/return 0;
}

警惕无穷递归!

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}Date(const Date& d);// 正确写法//Date(const Date& d)   // 错误写法:编译报错,会引发无穷递归//{//	_year = d._year;//	_month = d._month;//	_day = d._day;//}private:int _year;int _month;int _day;
};int main()
{Date d1;Date d2(d1);return 0;
}

1):内置类型成员完成值拷贝/浅拷贝

2):自定义类型成员会调用它的拷贝构造

自定义类型指向浅拷贝会出现两个问题:

  1. 析构两次,报错

  2. 一个函数修改会影响另一个函数


  1. DataMyQueue都不需要写。因为MyQueue里面会调用Stack,而Stack需要自己实现。Stack的实现和MyQueue无关。

  2. Stack需要自己实现

class Stack
{
public:Stack(int capacity = 4){cout << "Stack()" << endl;_a = (int*)malloc(sizeof(int) * capacity);if (nullptr == _a){perror("malloc申请空间失败");return;}_capacity = capacity;		_top = 0;}// st2(st1)Stack(const Stack& st){_a = (int*)malloc(sizeof(int) * st._capacity);if (nullptr == _a){perror("malloc申请空间失败");return;}memcpy(_a, st._a, sizeof(int) * st._top);_top = st._top;_capacity = st._capacity;}~Stack(){cout << "~Stack()" << endl;free(_a);_a = nullptr;_capacity = _top = 0;}private:int* _a = nullptr;int _top = 0;int _capacity;
};class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day;
};class MyQueue
{
private:Stack _pushst;Stack _popst;
};int main()
{//1):内置类型成员完成值拷贝/浅拷贝// 可以不写,默认生成的拷贝构造就可以用Date d1(2023, 4, 25);Date d2(d1);//Data(Data& d)里面的d是d1的别名//this指针是d2,也就是d2传给了this//2);自定义类型成员会调用它的拷贝构造//如果只传值,那么就会导致两个函数指向了同一个空间,析构函数调用的话就崩了// 而且就算不析构函数也会出问题。比如给其中一个函数赋值会影响另一个函数// 所以必须调用拷贝构造函数// 必须自己实现拷贝构造函数,实现深拷贝//栈后进先出,后创建的先析构,st2先析构,st1后析构//添加Stack(const Stack& st);前,会报错,因为st1和st2的析构函数指向了同一个空间,而一个空间无法释放两次//添加Stack(const Stack& st);后,不报错了//Stack(const Stack& st);就是我们自己实现的深拷贝Stack st1;Stack st2(st1);return 0;
}

注意:

在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。


为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据实际场景,能用引用尽量使用引用。

//这个采用引用返回是可以的,因为采用引用返回可以减少拷贝,而且函数结束后返回的值是没被销毁的
Stack& func1(){static Stack st;return st;
}
//这个采用引用返回是不可以的,因为函数结束后返回的值是被销毁了
Stack& func2(){Stack st;return st;
}int main(){func1();func2();return 0;
}

传引用返回要谨慎,传值引用没事

Stack& Func()
{static Stack st;//改成Stack st;就不行,因为Stack st;在Func()结束后就销毁了,就会导致拷贝构造传值错误st.Push(1);st.Push(2);st.Push(3);//...return st;
}int main()
{Stack ret = Func();cout << ret.Top() << endl;return 0;
}

class Date
{
public:Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// Date d2(d1);//是拷贝构造/*Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}*/// 不是拷贝构造,就是一个普通构造//Date(Date* p)//{//	_year = p->_year;//	_month = p->_month;//	_day = p->_day;//}//析构函数~Date(){cout << "~Date()" << endl;}
private:int _year;int _month;int _day;
};typedef int STDataType;
class Stack
{
public:Stack(int n = 4){_a = (STDataType*)malloc(sizeof(STDataType) * n);if (nullptr == _a){perror("malloc申请空间失败");return;}_capacity = n;_top = 0;}void Push(STDataType x){if (_top == _capacity){int newcapacity = _capacity * 2;STDataType* tmp = (STDataType*)realloc(_a, newcapacity *sizeof(STDataType));if (tmp == NULL){perror("realloc fail");return;}_a = tmp;_capacity = newcapacity;}_a[_top++] = x;}STDataType Top(){assert(_top > 0);return _a[_top - 1];}// st2(st1)Stack(const Stack& st){_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);if (nullptr == _a){perror("malloc申请空间失败");return;}memcpy(_a, st._a, sizeof(STDataType) * st._top);_top = st._top;_capacity = st._capacity;}~Stack(){cout << "~Stack()" << endl;free(_a);_a = nullptr;_top = _capacity = 0;}private:STDataType* _a;size_t _capacity;size_t _top;
};class MyQueue
{
public:
private:Stack pushst;Stack popst;
};void Func(Stack st){}void Func(int x){}Date f()
{Date ret;//...return ret;
}int main()
{Date d1(2024, 8, 9);//都是拷贝构造//自动生成的拷贝构造对内置类型成员变量会完成值拷贝 / 浅拷贝(一个字节一个字节的拷贝)Date d2(d1);Date d4 = d1;Date d5(f());Date d6 = f();//Satck不可以浅拷贝,因为Stack这里_a是一个指针,直接浅拷贝会导致两个指针指向同一块空间,析构就会崩溃Stack st1(10);Stack st2(st1);Func(st1);Func(1);MyQueue m1;MyQueue m2(m1);return 0;
}

这里就不调用拷贝构造了,因为这里是引用返回,不是传值返回

传值返回,返回的是值的拷贝,所以要调用拷贝构造

引用返回,返回的不是值的拷贝,返回的是它的别名,所以不调用拷贝构造

Date& operator=(const Date& d)//返回的是*this这个对象的别名,*this是d4
{if (this != &d)//以预防d1 = d1;的情况{_year = d._year;_month = d._month;_day = d._day;}return *this;
}

相关文章:

【C++】5.类和对象(3)

文章目录 3.析构函数析构函数的特点&#xff1a; 4.拷贝构造函数拷贝构造的特点&#xff1a; 3.析构函数 析构函数与构造函数功能相反&#xff0c;析构函数不是完成对对象本身的销毁&#xff0c;比如局部对象是存在栈帧的&#xff0c;函数结束栈帧销毁&#xff0c;他就释放了&…...

CTF-RCE

eval执行 ?cmdsystemctl("ls"); ?cmdsystemctl("ls /"); ?cmdsystemctl("cat /flag_27523); 命令注入 输入ip试试发先可以执行 127.0.0.1 查看一下看看有社么 127.0.0.1 | ls 试着看看php文件 127.0.0.1 | cat 297581345892.php 貌似这个文件有…...

谷歌账号登录时,多次验证后变成“您的计算机或网络可能在发送自动查询内容”,原因分析和解决建议

最近有多个朋友联系GG账号服务&#xff0c;反馈说谷歌账号登录的时候&#xff0c;提示谷歌账号活动异常&#xff0c;需要输入手机号验证&#xff0c;但是自己的手机号无法验证&#xff0c;要不提示无法用于进行验证&#xff0c;要不提示用于验证的次数过多。 有一些朋友第一次遇…...

【SpringMVC】详细介绍SpringMVC的执行流程

目录 1. 概念 2.SpringMVC工作原理 3. springMVC的简单使用 1.在pom.xml中导入相关依赖 2.在web.xml中配置dispatcherServlet 3.创建springMVC.xml核心配置文件 4. SPringMVC分层后各个模块的作用 1. 概念 什么是MVC&#xff1f; MVC是下面三个组件的简写&#xff0c;模型…...

工地云SaaS系统,通过物联网与可视化等先进技术的综合应用,搭建的智慧工地管理云平台源码

通过物联网与可视化等先进技术的综合应用&#xff0c;搭建智慧工地管理云平台。以绿色、安全施工管理为主线&#xff0c;从人员、设备、环境、监控#度管理、施工管理、工程管理等多个维度对现场要素进行信息化&#xff0c;实现数据实时更新、人员精确管理、风险及时预警、管理便…...

使用自定义注解和AOP解决登录校验问题

1、如果每次都从Redis获取token&#xff0c;会有很多冗余代码 2、使用面向切面编程的思想 在不改变源代码或者很少改变源代码的情况下&#xff0c;增强类的某些方法。 在业务代码之前设置 切入点 创建切面类&#xff0c;也就是比如登录校验的某些公共方法 切面类从切入点切入流…...

【数据结构初阶】队列

hello&#xff01; 目录 一、概念与结构 二、队列的实现 Queue.h Queue.c test.c 一、概念与结构 1、概念&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出的特性。 入队列&#xff1a;进行插入操作…...

《决胜B端 产品经理升级之路》 知识点总结

什么是b端产品&#xff1f; b端产品是指面向企业或组织的经营管理问题&#xff0c;旨在解决企业规模、成本、效率、品质和风控等方面的产品。这些产品主要帮助企业提高运营效率、降低成本、改善品质和控制风险等。b端产品适用于各种行业和企业类型&#xff0c;可以为企业带来深…...

2024年6月 青少年python一级等级考试真题试卷

202406 青少年软件编程等级考试Python一级真题 试卷总分数&#xff1a;100分 第 1 题 在使用turtle绘制图形时&#xff0c;如果要控制小海龟移动到 x 坐标为 200&#xff0c;y 坐标为150 的位置&#xff0c;以下代码能够实现效果的是&#xff1f;&#xff08; &#xff09; …...

TCFormer:通过标记聚类Transformer实现视觉识别

摘要 Transformer在计算机视觉领域得到了广泛应用&#xff0c;并取得了显著成功。大多数最先进的方法将图像分割成规则网格&#xff0c;并用视觉标记表示每个网格区域。然而&#xff0c;固定的标记分布忽略了不同图像区域的语义含义&#xff0c;导致性能次优。为了解决这个问题…...

haproxy实现七层负载均衡详解(基本配置与算法)

目录 一、haproxy介绍 1.1 haproxy工作原理 1.2 相关配置类型 二、全局配置 2.1相关参数说明 2.2实验示例 实验环境&#xff1a; 2.2.1 设置多进程 2.2.2 设置日志显示 三、proxies代理配置 3.1 参数说明 3.2 default配置相关属性参数 3.2. 配置前端fronttend后端ba…...

海量日志数据收集监控平台应该怎么设计和实现

设计和实现一个海量日志数据收集和监控平台&#xff0c;需要考虑以下几个关键方面&#xff1a;数据采集、数据存储、实时处理、监控与告警、可视化分析、扩展性和高可用性。以下是一个详细的设计和实现方案&#xff1a; 1. 需求分析 日志来源&#xff1a;明确日志的来源&…...

Windows图形界面(GUI)-MFC-C/C++ - CSliderCtrl

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 CSliderCtrl 创建滑动条 设置滑动条属性 成员函数 消息处理 注意事项 示例代码 CSliderCtrl 创建滑动条 在对话框编辑器中&#xff0c;从工具箱中拖拽一个Slider Control到对话框…...

常见中间件漏洞复现之【WebLogic】!

Weblogic介绍 WebLogic是美国Oracle公司出品的⼀个application server&#xff0c;确切的说是⼀个基于JAVAEE架构的中间件&#xff0c;默认端⼝&#xff1a;7001 WebLogic是⽤于开发、集成、部署和管理⼤型分布式Web应⽤、⽹络应⽤和数据库应⽤的Java应⽤服务器。将Java的动态…...

Linux服务器中限制远程IP登录的深入指南

在当今的数字化时代&#xff0c;Linux服务器的安全性是企业和个人用户不可忽视的重要方面。远程登录&#xff0c;尤其是通过SSH&#xff08;Secure Shell&#xff09;协议&#xff0c;是服务器管理中最常见的操作之一。然而&#xff0c;不限制远程登录的IP地址可能会暴露服务器…...

卫星通信中的拥塞控制算法

结论:现有的Cubic和BBR2算法可直接用于卫星通信网络的拥塞控制中,专为卫星设置的拥塞控制算法目前没有集成到系统中,但各自的性能表现需要根据实测情况进行取舍。 TCP Hybla...

全网​​​​​​​​超详细haproxy七层代理

一&#xff1a;负载均衡 1、概念 负载均衡&#xff1a; Load Balance &#xff0c;简称 LB &#xff0c;是一种服务或基于硬件设备等实现的高可用反向代理技术&#xff0c; 负载均 衡将特定的业务(web 服务、网络流量等 ) 分担给指定的一个或多个后端特定的服务器或设 备&…...

Docker日志文件全局配置

这段配置是Docker容器的日志驱动配置&#xff0c;具体来说是json-file日志驱动的配置。这个配置的作用是定义容器日志文件的大小和数量限制。 {"log-driver": "json-file","log-opts": {"max-size": "500m","max-file…...

bia文件中码偏差对实时PPP解算分析

1. 码偏差对定位影响 码偏差对未知收敛时间有影响&#xff0c;对最终精度影响不大&#xff08;权比1000:1&#xff09;...

探索list与iterator的区别及yield的用法

1 问题 探索list与iterator的区别探索yield的用法 2 方法 通过网上学习后了解到 List返回的类型是list&#xff0c;list只会查询一级缓存。list()中返回的List中每个对象都是原本的对象。查询的时候没遍历一个对象会产生一条sql&#xff1b;而iterator这个迭代器返回的类型是it…...

github技巧和bug解决方法短篇收集

有一些几句话就可以说明白的观点或者解决的的问题&#xff0c;小虎单独收集到这里。 Commits没有算入每天的activity fork的仓库是不算的。 Commits made in a fork will not count toward your contributions. 参考&#xff1a; Contribution activity not shown for github…...

学习笔记五:在k8s中安装EFK组件(elasticsearch+fluentd+kibana)

在k8s 1.3安装EFK组件 前置条件上传压缩包安装nfs供应商创建nfs作为存储的供应商通过deployment创建pod用来运行nfs-provisioner 安装elasticsearch组件安装kibana组件安装fluentd组件 前置条件 查看k8s版本 kubectl get node -owide相关安装包 链接&#xff1a;https://pan.ba…...

Golang编译-如何忽略某些文件去编译

在 Go 语言中&#xff0c;编译好的二进制文件不会被再次加入到编译过程中。Go 编译器只会编译源代码文件&#xff08;如 .go 文件&#xff09;&#xff0c;而不会将已经编译好的二进制文件&#xff08;如可执行文件或静态库&#xff09;作为输入来进行编译。 详细解释&#xf…...

有哪些适合中型企业的人力资源管理系统推荐?

本文主要介绍了以下几款人力资源管理系统&#xff1a;Moka、OrangeHRM、Verint、希沃人事、UKG Pro、大易Dayee、DingTalk、致远OA、卓望ShineHR、GoCo。 在选择人力资源管理系统时&#xff0c;中型企业面临着诸多挑战&#xff1a;如何确保系统既能满足现有需求&#xff0c;又能…...

活动回顾|首次 Cloudberry Database Meetup · 北京站成功举办

8 月 3 日&#xff0c;由酷克数据 HashData 主办的 Cloudberry Database Meetup 北京站活动圆满结束。本次 Meetup 以“以开源应对 Greenplum 闭源&#xff0c;原厂开发者再聚首”为主题&#xff0c;深入探讨了 Greenplum 闭源所带来的影响&#xff0c;并聚焦于 Cloudberry Dat…...

C语言 软件设计的七大原则,及其应用案例

1. 单一职责原则 (Single Responsibility Principle, SRP) 定义&#xff1a; 一个模块或函数应当只有一个引起变化的原因。 应用案例&#xff1a; 在嵌入式系统中&#xff0c;可以将传感器数据的读取和处理分开成不同的函数。例如&#xff1a; // 读取传感器数据的函数 floa…...

初学嵌入式-C语言常犯错误详解

1、对于下面这道题&#xff0c;估计有很多人会选择B答案&#xff0c;但其实答案是D 2.int a10, b9,c9,d; d b || (a>c)&#xff0c;请问上述代码执行完毕后a b c d的值分别是 。 A、10 9 10 9 B、10 10 10 1 C、10 9 10 1 D、10 10 9 1 答案解释&#xff1a; 在C语言…...

Golang 语法入门

Golang 语法入门 Hello World package mainimport "fmt"func main() {fmt.Println("hello world") }变量 package mainimport "fmt"// 全局变量 var ans 123 var cnt intfunc main() {// 单个局部变量a : 114514// 多个局部变量b, c : 114, …...

Filebeat+Kafka+ELK

架构&#xff1a; 部署&#xff1a; #配置nginx&#xff0c;部署filebeat systemctl stop firewalld setenforce 0 systemctl restart nginx#解压filebeat tar -xf filebeat-6.7.2-linux-x86_64.tar.gz mv filebeat-6.7.2-linux-x86_64 filebeat#日志收集 cd firebeat vim fil…...

Python 为Excel单元格设置填充\背景色 (纯色、渐变、图案)

在使用Excel进行数据处理和分析时&#xff0c;对特定单元格进行背景颜色填充不仅能够提升工作表的视觉吸引力&#xff0c;还能帮助用户快速识别和区分不同类别的数据&#xff0c;增强数据的可读性和理解性。 本文将通过以下三个示例详细介绍如何使用Python在Excel中设置不同的单…...