如何将建设工程合同备案信息在WordPress网站中全局置顶?
摘要:建设工程合同备案网站,wordpress 全局置顶,群晖配置wordpress,wordpress如何汉化主题💖作者:小树苗渴望变成参天大树 ❤️&#x1fa7
建设工程合同备案网站,wordpress 全局置顶,群晖配置wordpress,wordpress如何汉化主题#x1f496;作者#xff1a;小树苗渴望变成参天大树 ❤️#x1fa79;作者宣言#xff1a;认真写好每一篇博客 #x1f4a8;作者gitee:gitee #x1f49e;作者专栏#xff1a;C语言,数据结构初阶,Linux,C 如 果 你 喜 欢 作 者 的 文 章 #xff0c;就 给 作 者 点… 作者小树苗渴望变成参天大树 ❤️作者宣言认真写好每一篇博客 作者gitee:gitee 作者专栏C语言,数据结构初阶,Linux,C 如 果 你 喜 欢 作 者 的 文 章 就 给 作 者 点 点 关 注 吧 文章目录 前言一、案例引入二、拷贝构造三、案例引入四、运算符重载五、总结 前言
今天博主又来更新新的文章了今天我们接着上面的内容就下两个默认成员函数讲完这两个剩下来的两个就简单了因为用到也不多今天讲的这个两个也特别的关键尤其是第一个也不好理解我尽量使用易懂的语言给大家讲解而且要用到之前的栈类日期类myQueue类话不多说我们开始进入正文。 一、案例引入
在我们之前学习的内置类型我定义一个整型变量
int a10;此时我想定义一个和a是一样的变量怎么做
int ba;内置类型是这样就可以解决问题了。 对于自定义类型我们如果也这样呢
Date d1(2023,5,1);
Date d2d1;在C里面是不允许这么赋值的在传营参的时候也不是直接把对象1直接赋值给对象2必须要通过调用拷贝构造函数去实现。 拷贝构造函数其实是特殊的构造函数也是完成初始化操作的所以有些特性和构造函数一样无返回值函数名和类名相同形参是固定的 拷贝构造函数 只有单个形参该形参是对本类类型对象的引用(一般常用const修饰)在用已存在的类类型对象创建新对象时由编译器自动调用。 我们来看具体写法 大家可以看到完成我们想要的效果。 解决困惑 1.为什么要加引用 我给大家举一个例子
class Date
{
public:void print(){cout _year _month _day endl;}Date()//无参构造函数{_year 1;_month 1;_day 1;}Date(const Date d)//拷贝构造函数{_year d._year;_month d._month;_day d._day;}
private:int _year;int _month;int _day;
};void func(int m){}
void func(Date d){}
int main()
{Date d1;//调用无参构造器初始化d1;func(10);//对于传内置类型是直接把值赋给形参在一开始就讲过了func(d1);//这个传给形参需要调用拷贝构造然后拷贝构造里面的形参也是通过实参传过去有会形成新的拷贝构造我们一起来看调用会出现什么情况//Date d2(d1);//使用d1对象初始化d2,是两个不同的对象但是里面的内容是一样的//d1.print();/*d2.print();*/return 0;
}大家看到我们箭头指向第二个func的时候不是直接跳到函数体里面而是直接跳到拷贝构造那里了因为现在的编译器都强制检查不使用引用就会报错如果不加能调试你就会看到箭头一致在拷贝构造哪一行永远进不去拷贝构造体里面无线递归下去就像下面的情况一样 这时候就需要使用到引用形参就是实参的别名不需要像传值一样还要创建历史变量在赋值过去所以之前的传值的拷贝构造不行传引用就直接使用也不需要创建临时变量所以可以直接进入函数体里面这一定是最不好理解的所以大家一定对于调用函数的传参机制要弄明白而且要之前自定义类型和内置类型的赋值方式是不一样的传参就是一种赋值 2.为什么要加const 加const是怕有人写反例如 这样不仅仅没有给d2进行初始化反而让自己的值也改变了所以加一个const就刚好的解决了这个问题 通过上面的例子我们大致知道了拷贝构造函数的用法以及拷贝构造函数的特征有那些也解释了拷贝构造使用时候该注意的细节是什么算是入门了但拷贝构造的细节往往不止这些让我们正式进入拷贝构造的讲解 二、拷贝构造
在案例引用那一块我已经介绍了拷贝拷贝构造的一部分细节在文章的开头我提到过拷贝构造函数也是默认成员函数不写编译器会默认生成的那我们来看看不写会出现什么情况 大家发现这写不写拷贝构造效果都一样啊 大家在来看一下栈类如果这样会出现什么情况 我们发现我们不写构造函数就会出现问题我们通过调试来看看什么时候出现这样的错误 我们来看一下图解 报错的原因是对同一块地址析构了两次在st1结束时调用析构释放了那块空间在st2结束时有调用了析构函数对已经释放的空间在次释放在动态内存管理那一节明确说过这样是不可以的。 那为什么会出现这样的情况呢 拷贝构造在不显示的时候并不会像构造函数一样对内置类型不做任何处理而是会将内置类型按照字节拷贝去进行拷贝的也就是值拷贝或者叫浅拷贝跟memcpy类似刚才那种情况是那三个成员变量都是内置类型指针也属于内置类型所以才会出现刚才的问题那么怎么解决这个问题显然默认生成的肯定不行就需要自己写一个拷贝构造函数采取深拷贝这里就提一下后面的博客会重点介绍我们来看一下深拷贝是怎么解决这个问题的
Stack(const Stack st){_array (int*)malloc(sizeof(int) * st._capacity);if (_array NULL){perror(malloc:);exit(-1);}memcpy(_array, st._array, sizeof(int) * st._size);_size st._size;_capacity st._capacity;}相信大家应该知道怎么处理了吧并且一开始那种不止是析构两次的问题在操作的是另一个会影响另一个因为公用一块空间 可以简单的理解拷贝构造函数就是为深拷贝而生的也体会到了创造者的厉害之处 但是刚才对于默认生成的拷贝构造函数对内置类型会做处理对自定义类型呢我们来看效果 对于自定义类型编译器默认生成的拷贝构造会自动调用自定义类中的拷贝构造这一点和构造函数析构函数类似希望大家可以更好的理解 什么时候需要自己写拷贝构造呢
都是内置类型并且没有动态申请资源的就可以不用自己写拷贝构造。全部都是自定义类型的时候也不需要写典型就是两个栈实现队列的时候 具体问题具体分析希望大家可以理解。 到这几乎把拷贝构造讲解清楚了大家一定要好好消化接下来我将讲解运算符重载函数 三、案例引入
我们来看一下整型怎么比较大小的
int a10;
int b20;
ab;那我们来看一下自定义类型
Date d1(2023,5,1);
Date d2(2022,4,30);
d1d2;我们看到显然这样是不行的我们需要写一个函数来进行比较大小我直接将函数体内容写出来
bool Less(const Date x1, const Date x2)
{if (x1._year x2._year)//年小就小{return true;}if (x1._year x2._year x1._month x2._month)//年不小月小就小{return true;}if (x1._year x2._year x1._month x2._month x1._day x2._day)//年月不小天小就小{return true;}return false;//所以小的都找到剩下的就是大的
}大家看我们上面都是报错原因就是我在类外写的函数体恰好成员变量是私有的只能在类里面使用所以这个时候就会报错就将成员变量的权限改成共有的就可以了也可以将函数放到类里面但是还有好多细节一会在说 大家可能认为这么解决问题很简单但是如果有人的函数名写的千奇百怪的怎么办又不写注释那么我们使用起来就非常的难受我们希望的是一开始那种直接使用运算符来进行比较清晰明了这时候就要使用运算符重载来做
我先将成员变量的权限变成共有的方便运行平时都是私有的安全性高我们在运算符前面加一个operator就可以重载运算符因为输出流插入的优先级高于运算符所以要加括号
cout (d1d2)endl;
cout operator(d1, d2) endl;//这两种写的效果一样在底层的汇编两者是一样的指令。 到现在大家应该已经算是初步了解的运算符重载他的目的就是将原来的运算符进行一个新的定义因为自定义类型的大小比较只有设计者自己知道但为了让代码看的显而易懂创造者就引出了运算符重载。接下来正式开始介绍运算符重载也是给一个新的知识做铺垫 四、运算符重载
为什么要讲运算符重载一是他非常重要二是方便讲赋值运算符重载他是默认的成员函数。在案例引用的时候我们发现将函数体写在外面成员函数出现了无法访问的情况那我们将函数写在类中看看需要注意什么 出现参数太多的情况原因是成员函数都会有一个隐含的this所以这里面报参数过多我们大部分的运算符都是二元运算符所以在运算符重载几乎都是只有一个参数 这样就可以了上面那种方式就不可以这么写了
cout (d1d2)endl;
cout d1.operator(d2) endl;//必须写成这样的形式,d1.才能将d1的地址传给this指针大家应该知道元素在类中是怎么使用的吧接下来讲解一个重要的知识赋值运算符重载上面是小于运算符重载这也是默认成员函数只有不写就会自动生成让我们这个函数是怎么使用的和注意的细节
赋值运算符重载 对于赋值运算符重载我们只能卸载类里面不能写成全局的 用一个已经存在的对象去初始化另一个的对象这是拷贝构造 已经存在的两个对象之间的赋值拷贝这是赋值运算符重载 大家一定要理解这两个不然一开始很容易将拷贝构造和赋值运算符搞混觉得是同一个东西实际上还是有本质的差别 d1成功被d2赋值了这是目前写的一个最简单版本的赋值运算符重载相比较拷贝构造他又返回值而拷贝构造没有但是这种写的不太完美万一我想连续赋值呢
d4d3d2d1;我们以整型为例
int i,j,k0;
ijk0;在整型的时候可以这样写原因是k0返回的是k,jk返回的是j,ij返回的是i每个运算符返回的都是对应类型的那么我们赋值运算符重载是不也要有类型返回值 这么写还是不太完美用值返回我们在函数那一将说过返回的值需要创建临时变量先将值拷贝到临时变量上在返回而我们上面说过对于自定义类型的拷贝需要调用拷贝构造我们来看看效果 有四次返回就要四次调用拷贝构造怎么解决这个问题呢我们就需要使用到引用返回对于引用返回我们需要主要几个点局部变量不能哟个引用很危险静态的可以用引用对于这里我们的this是局部变量出了我们的赋值运算符函数就会被销毁但是我们返回的是*this,*this就是对象了他的生命周期是main函数所以不会随着赋值运算符的结束而销毁所以可以使用引用返回 这里就不用调用拷贝构造减少消耗提高效率但是我们还需要完善有的人会这么写
d1d1;这样没有什么意义避免这样我们需要加一个if判断 相同对象的地址肯定能够是一样的有的人会这么写
if(*this!d)这样写的前提是重载了!运算符那这样成本太高不如直接用地址来判断。
说到这里大家应该可以体会到我之前写的C入门那篇博客的主要性了吧,前后知识都是连贯的 赋值运算符重载也是默认的成员函数不写会默认生成我们看看默认生成的会干那些事 大家看到我们没有写居然达到了同样的效果那我们写他为了干什么对于内置类型我们会完成浅拷贝但是又自定义类型我们就会去调用他的赋值运算符重载我们来看效果 我们来看看效果会去调用栈里面的赋值运算符重载 所以赋值运算符重载的操作行为和构造函数的行为一样对内置类型完成浅拷贝对于自定义类型去调用他的赋值运算符。 什么时候需要写赋值运算符重载
全部都是内置类型的时候不需要写日期类有动态开辟的空间需要写栈类都是自定义类型的不需要写MyQueue类
注意
不能通过连接其他符号来创建新的操作符比如operator重载操作符必须有一个类类型参数用于内置类型的运算符其含义不能改变例如内置的整型不 能改变其含义作为类成员函数重载时其形参看起来比操作数数目少1因为成员函数的第一个参数为隐藏的this.* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出 现。
五、总结
今天重点讲解了拷贝构造和运算符重载这都是默认成员函数比较重要的知识点大家一定要学号后面的学习都是围绕这些基础展开讲解的接下来我会写一篇博客来完善我们的日期类把我们这两篇总结的知识点运用一下我们一个六个默认成员函数目前已经讲解了四个剩下来的两个不是重点后面我在单独写一篇博客给大家简单介绍一下即可现在我们的任务就是完成这两篇博客的学习和练习。希望大家都来学到知识。我们下篇再见
