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

c++的类和对象(中):默认成员函数与运算符重载(重难点!!)

前言 

Hello, 小伙伴们,我们今天继续c++的学习,我们上期有介绍到c++的部分特性,以及一些区别于c语言的地方,今天我们将继续深入了解c++的类和对象,探索c++的奥秘。

好,废话不多说,开始我们今天的学习。 

1.类默认成员函数

默认成员函数就是用户没有显示实现,编译器会自动生成的函数称为默认成员函数。一个类,我们不写的情况下,编译器会默认生成6个默认函数,需要注意的是这六个函数中重要的是前4个,最后两个取地址重载不重要,我们稍微了解一下就好。其次,c++11以后还会增加两个默认的函数,移动构造和移动赋值,这个我们后面再讲解。默认成员函数十分的重要,也比较复杂,我们要从两个方面去学习:

第一:我们不写默认函数时, 编译器默认的函数行为是什么,是否能满足我们的要求。

第二:编译器默认生成的函数不满足我们的要求时,我们要自己去实现符合要求的函数。

 

1.1构造函数 

构造函数就是特别的成员函数,需要注意的是,构造函数虽然名为构造,但是构造函数的主要任务不是开辟空间创建对象(我们之前使用的局部对象是栈帧创建时,就开辟好的),而对象的实例化时初始化对象。构造函数的本质就是要替代我们之前在实现Stack 和 Queue类中的Init函数功能,构造函数自动调用的特点就完美的替代了Init函数。

构造函数的特点:

1.函数名与类名相同。会自动生成一个无参数的默认构造函数,一旦用户显示定义,编译器就不会再生成默认的

2.无返回值(返回值啥的都不需要给,也不需要void, 也不需要纠结, c++的一定就是如此)。
3.对象实例化时西永会
和全缺省函数也是默认构造函数,总结一下就是不传实参就可

自动调用构造函数。

4.构造函数可以重载。

5.如果类中没有显示定义的构造函数,则c++编译器

构造函数。

 6.无参的构造函数、全缺省构造函数、我们不写构造函数时编译器自己默认生成的构造函数,都叫做默认构造函数。但着三个函数有且只有一个存在于一个类中,不能同时存在。无参构造函数和全缺省函数虽然构成函数重载,但是调用时产生歧义。要注意的是很多的同学会认为默认构造函数是编译器默认生成的,但实际上无参构造函数

以调用的构造函数就叫默认构造

7.我们不写,编译器默认生成的构造,对内置类型的成员变量初始化没有要求,也就是说是否初始化是不确定的,看编译器。对于自定义类型成员变量,要求调用这个成员变量的默认构造函数初始化。如果这个成员便变量没有默认构造函数,那么就会报错,我们要初始化这个变量,需要用初始化列表才能解决,初始化列表我们到了后面会详细介绍!!

说明: c++把类型分为内置类型(基本类型)和自定义类型。内置类型就是语言原生数据类型,如:int/char/double/指针等类型,自定义类型就是我们使用class和struct等关键字自己定义的类型。

我们来看看下面的代码实例:

#include<iostream>
using namespace std;
class Date
{public :// 1.⽆参构造函数Date(){_year = 1;_month = 1;_day = 1;} // 2.带参构造函数Date(int year, int month, int day){_year = year;_month = month;_day = day;} // 3.全缺省构造函数/*Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}*/void Print(){cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};
int main()
{// 如果留下三个构造中的第⼆个带参构造,第⼀个和第三个注释掉// 编译报错:error C2512: “Date”: 没有合适的默认构造函数可⽤Date d1; // 调⽤默认构造函数Date d2(2025, 1, 1); // 调⽤带参的构造函数// 注意:如果通过⽆参构造函数创建对象时,对象后⾯不⽤跟括号,否则编译器⽆法// 区分这⾥是函数声明还是实例化对象// warning C4930: “Date d3(void)”: 未调⽤原型函数(是否是有意⽤变量定义的?)Date d3();d1.Print();d2.Print();return 0;
}

1.2析构函数

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

析构函数的特点

  • 析构函数名就是类名前面加上字符~。
  • 无参数返回值。(这里和构造函数十分的相似,也不需要加 void).
  • 一个类只能有一个析构函数。若没有显示定义,系统就会自动生成默认的析构函数。
  • 对象的生命周期结束时,系统会自动调用析构函数。
  • 跟构造函数类似,我们不写编译器就会自动生成析构函数对内置类型成员不做处理,自定义类型成员就会调用他的析构函数。
  • 还需要注意的是我们显示写析构函数,对于自定义类型成员也会调用他的析构,也就是说,自定义类型成员无论在什么样的情况下都会自动调用自己的析构函数!!
  • 如果类中没有申请资源,析构函数就可以不写,直接使用编译器生产的默认函数,如Date;如果默认生成的析构函数就够用,我们就不需要再显示其结构, 比如:MyQueue;但是有资源的申请时,一定要自己写析构函数,否则会造成资源泄露,如:Stack。
  • 一个局部域的多个对象,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语言实现的栈结构,我们可以明显的观察到c++相较于C语言明显的优势。

我们发现有了析构函数和构造函数确实方便了很多,也不会在担心忘记写Init函数和Destroy函数了,我们写代时也方便了不少!!

1.3拷贝构造函数

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

拷贝构造的特点:

  • 拷贝构造函数是构造函数的一个重载。
  • 拷贝构造函数的第一个函数必须是类类型对象的引用,使用传值方式编译器直接报错,因为语法逻辑上会引起无穷递归调用、拷贝构造函数也可以有多个参数,但是第一个参数必须是类类型对象的应用, 后面的参数必须有缺省值。
  • c++规定的自定义类型对象进行拷贝行为,必须调用靠别构造函数,所以这里自定义类型传值传参和传值返回都会调用拷贝调用完成。
  • 若显示未定义拷贝构造,编译器会生成自动的拷贝构造函数,自动生成的拷贝构造对内置类型成员变量完成值拷贝/浅拷贝(一个字节一个字节的拷贝),对自定义类型成员变量会调用它的拷贝构造。
  • 像Date这样的类成员变量全是内置类型且没有指向那个资源,编译器自动生成的拷贝构造就可以完成值的拷贝,所以不需要我们显示拷贝构造。但是像Stack这样的类,虽然也是内置类型,但是_a指向的资源,编译器自动生成拷贝构造就不符合我们现在的要求了,所以需要我们自己来实现深拷贝(对指向的资源也进行拷贝)。像MyQueue这样的类型内部主要是自定义类型Stack成员,编译器自动生成的拷贝构造。这里有一个小技巧,如果一个类显示实现了析构并释放资源那么他就需要显示拷贝构造,否则就不需要。
  • 传值返回会产生一个临时对象调用拷贝构造,传值引用返回,返回的是返回对象的别名(引用),没有产生拷贝。但是如果返回对象是一个当前函数局部域的局部对象,函数结束就销毁了,那么使用引用返回就有问题,这时的引用相当于一个野引用,类似一个野指针一样。传引用返回可以减少拷贝,但是一定要确保返回对象,在当前函数结束后还在,才能用引用返回。

我们来看下面的例子:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{public :Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;} // 编译报错:error C2652 : “Date”: ⾮法的复制构造函数: 第⼀个参数不应是“Date”//Date(Date d)Date(const Date & d){_year = d._year;_month = d._month;_day = d._day;} Date(Date * d){_year = d->_year;_month = d->_month;_day = d->_day;}void Print();private:int _year;int _month;int _day;
};
void Date:: Print()
{cout << _year << "-" << _month << "-" << _day << endl;
}
void Func1(Date d)
{cout << &d << endl;d.Print();
} 
// Date Func2()
Date & Func2()
{Date tmp(2024, 7, 5);tmp.Print();return tmp;
} 
int main()
{Date d1(2024, 7, 5);// C++规定⾃定义类型对象进⾏拷⻉⾏为必须调⽤拷⻉构造,所以这⾥传值传参要调⽤拷⻉构造// 所以这⾥的d1传值传参给d要调⽤拷⻉构造完成拷⻉,传引⽤传参可以较少这⾥的拷⻉Func1(d1);cout << &d1 << endl;// 这⾥可以完成拷⻉,但是不是拷⻉构造,只是⼀个普通的构造Date d2(&d1);d1.Print();d2.Print();//这样写才是拷⻉构造,通过同类型的对象初始化构造,⽽不是指针Date d3(d1);d2.Print();// 也可以这样写,这⾥也是拷⻉构造Date d4 = d1;d2.Print();// Func2返回了⼀个局部对象tmp的引⽤作为返回值// Func2函数结束,tmp对象就销毁了,相当于了⼀个野引⽤Date ret = Func2();ret.Print();return 0;
}

 2.赋值运算符的重载

2.1运算符的重载

  1. 当运算符被用于类类型的对象时,c++语言允许我们通过对运算符重载的形式指定其新的含义。c++规定类类型对象使用运算符时,必须转换调用对应运算符的重载,若没有对饮的运算符重载,则会编译报错。
  2.  运算符重载是具有特殊名字的函数,他的名字是有operaor和后面的要定义的运算符共同构成的。和其他函数一样,它具有其返回类型和参数列表以及函数体。
  3. 重载运算符的参数个数和该运算对象的数量一致。一元运算符有一个参数,二元运算符有两个参数,二元运算符的左侧运算对象传给第一个参数,右侧运算对象传给第二个参数。
  4. 如果一个重载运算符函数是成员函数,则它的第一个运算对象默认传给隐士指针---this指针,因此运算符重载作为成员函数时,参数比运算对象少一个。
  5. 运算符重载后,其优先性和结核性与对应的内置类型运算符保持一致。
  6. 不能通过连接语法中没有的符号来创建新的操作符,比如:operator@。
  7. .*   ::  sizeof  ?:     .  注意前面的操作符不能重载。
  8. 重载操作符至少有一个类类型参数,不能通过运算符重载改变内置类型对象的含义!!
  9. 一个类需要重载那些运算符,是看运动算符在重载后承载了什么样的意义。
  10. 重载++运算符时,有前置++,和后置++,而运算重载函数都是通过operator++来实现的,没有办法很好的来区分,c++规定,,后置的++重载时增加一个int形参,跟前置++构成函数重载,方便区分。
  11. 重载<<和>>时,需要重载为全局函数,因为重载成员函数时,this指针默认会抢占形参的第一个位置,第一个形参位置是左侧运算对象,调用时变成了<<cout,不符合使用习惯和可读性。重载为全局函数把ostram和istream1放到第一个形参位置就i行了,第二个形参位置当类类型对象。

比如,我们来看下面的代码:

#include<iostream>
using namespace std;
// 编译报错:“operator +”必须⾄少有⼀个类类型的形参
int operator+(int x, int y)
{return x - y;
}
class A
{
public :
void func()
{
cout << "A::func()" << endl;
}
};
typedef void(A::* PF)(); //成员函数指针类型
int main()
{// C++规定成员函数要加&才能取到函数指针PF pf = &A::func;A obj;//定义ob类对象temp// 对象调⽤成员函数指针时,使⽤.*运算符(obj.*pf)();return 0;
}

3.日期类的实现

接下来我们实现一个日期类应用的底层逻辑,结合上面的知识,我们来试着实现一下把 :

首先我们还是要创建三个文件:

接下来我们展示代码:

Date.h

 

#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
class Date
{
public:Date(int year  = 2023, int month = 8, int day = 10);//~Date();void Print();bool operator<(const Date& d);bool operator>(const Date& d);bool operator<=(const Date& d);bool operator>=(const Date& d);bool operator==(const Date& d);bool operator!=(const Date& d);Date& operator+=(int x);Date& operator+(int x);Date& operator-=(int x);Date& operator-(int x);//++dDate& operator++();//d++Date operator++(int);//两个日期相减隔开的天数int operator-(const Date& d);int GetMonthDay(int month, int year){assert(month > 0 && month <= 12);static int monthday[13] = { -1, 31,28,31,30,31,30,31,31,30,31,30,31 };//高频率的调用,使用静态函数就会提高效率,放在了静态区if (month == 2 && (year % 4 == 0 && year % 100 != 0 || year % 400 == 0))return 29;return monthday[month];}
private:int _year;int _month;int _day;
};

 Date.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"
Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;
}
void Date:: Print()
{cout << _year << "/" << _month << "/" << _day << endl;
}
bool Date::operator<(const Date& d)
{if (_year < d._year)return true;else if (_year == d._year &&_month < d._month)return true;else if (_year == d._year && _month == d._month&&_day < d._day)return true;return false;
}
bool Date::operator>(const Date& d)
{return !(*this <= d);
}
bool Date::operator<=(const Date& d)
{return *this < d || *this == d;
}
bool Date::operator>=(const Date& d)
{return *this > d || *this == d;
}
bool Date::operator==(const Date& d)
{return _year == d._year && _month == d._month&& _day == d._day;
}
bool Date::operator!=(const Date& d)
{return !(*this == d);
}
Date& Date::operator+=(int x)
{if (x < 0){return *this -=  -x;}_day += x;while (_day > GetMonthDay( _month,_year)){_day -= GetMonthDay(_month, _year);_month++;if (_month > 12){_year++;_month = 1;}}return *this;
}
Date& Date::operator+(int x)
{Date tmp = *this;tmp += x;return tmp;
}
Date& Date::operator -= (int x)
{if (x < 0){return(*this) += -x;}_day -= x;while (_day <= 0){_day += GetMonthDay(_month, _year);_month--;if (_month == 0){_year--;_month = 12;}}return *this;
}
Date& Date::operator-(int x)
{Date tmp = *this;tmp -= x;return tmp;
}//++d
Date& Date::operator++()
{*this += 1;return *this;
}
//d++
Date Date::operator++(int)
{Date tmp = *this;*this += 1;return tmp;
}
//使用逐一++的方法来判断相差的天数
int Date::operator-(const Date& d)
{Date big = *this;Date small = d;int flag = 1;if (*this < d){big = d;small = *this;flag = -1;}int count = 0;while (big != small){small++;count++;}return count * flag;
}

Test.cpp

#define _CRT_SECURE_NO_WARNINGS 1#include"Date.h"
int main()
{Date d1(2023, 4, 5);Date d2 = d1 + 100;d2.Print();d1.Print();
//	d1 += 100;d1.Print();d1 -= 5;d1.Print();(d1 += (-100)).Print();(d1 -= (-100)).Print();//cout << (d3 ? "true" : "false") << endl;cout << endl;d1.Print();d2.Print();cout << d1 - d2 << endl;return 0;
}

好,今天的学习就到这里,我们下期再见!!

相关文章:

c++的类和对象(中):默认成员函数与运算符重载(重难点!!)

前言 Hello, 小伙伴们&#xff0c;我们今天继续c的学习&#xff0c;我们上期有介绍到c的部分特性&#xff0c;以及一些区别于c语言的地方&#xff0c;今天我们将继续深入了解c的类和对象&#xff0c;探索c的奥秘。 好&#xff0c;废话不多说&#xff0c;开始我们今天的学习。…...

Android .kl按键布局文件

1.介绍 一个硬件按键的处理流程大致为&#xff1a;当用户按下或释放一个键时&#xff0c;键盘硬件会生成一个扫描码scan code&#xff0c;然后操作系统读取这个scan code&#xff0c;并将scan code扫描码映射到虚拟键码key code&#xff0c;最后操作系统根据映射的keycode生成…...

Java每日一练_模拟面试题6(JVM的GC过程)

一、JVM虚拟机组成 JVM五大内存区域&#xff1a;程序计数器&#xff0c;Java虚拟机栈&#xff0c;本地方法栈&#xff0c;java堆&#xff0c;方法区。 堆被划分为两个区域&#xff1a;年轻代(Young)、老年代(Tenured)。年轻代又被划分为三个区域&#xff1a;Eden、From Surviv…...

数据防泄密软件推荐|(6大数据防泄密软件推荐!)

很多朋友在后台私信&#xff0c;什么是数据防泄密软件&#xff0c;有哪些数据防泄密软件推荐。 今天小编将从定义出发&#xff0c;深入浅出地介绍这一技术的工作原理、应用场景以及实现方式。 一、什么是文档透明加密&#xff1f; 文档透明加密是一种在用户无感知的情况下对文…...

Codeforces 874 div3 A-G

A. Musical Puzzle 分析 每两个相邻的字母都要录制一段&#xff0c;开个set记录一下&#xff0c;然后输出set的大小 C代码&#xff1a; #include<iostream> #include<set> using namespace std; void solve(){int n;string s;cin>>n>>s;set<strin…...

暑期数据结构 空间复杂度

3&#xff0e;空间复杂度 空间复杂度也是一个数学表达式&#xff0c;是对一个算法在运行过程中临时占用存储空间大小的量度。 空间复杂度不是程序占用了多少bytes的空间&#xff0c;因为这个也没太大意义&#xff0c;所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟…...

【Android Studio】图标一键生成 Image Asset Studio(一键各机型适配图标生成工具-告别一个一个替换)

文章目录 方法一&#xff1a;原始替换方法二&#xff1a;Image Asset Studio 方法一&#xff1a;原始替换 https://blog.csdn.net/xzzteach/article/details/140821856 方法二&#xff1a;Image Asset Studio 自动替换所有机型图标...

C++ | Leetcode C++题解之第332题重新安排行程

题目&#xff1a; 题解&#xff1a; class Solution { public:unordered_map<string, priority_queue<string, vector<string>, std::greater<string>>> vec;vector<string> stk;void dfs(const string& curr) {while (vec.count(curr) &am…...

使用Python实现简单的网页爬虫:抓取网站标题

使用Python实现简单的网页爬虫:抓取网站标题 在当今数据驱动的时代,网络爬虫(Web Crawler)成为了获取和分析网络数据的重要工具。无论是数据科学、市场分析还是学术研究,爬虫都能帮助我们从互联网上提取有价值的信息。本文将介绍如何使用Python实现一个简单的爬虫,抓取某…...

视觉SLAM ch3—三维空间的刚体运动

如果对于某些线性代数的知识不太牢固&#xff0c;可以看一下我的另一篇博客&#xff0c;写了一些基础知识并推荐了一些视频。 旋转矩阵 单元所需的线代基础知识https://blog.csdn.net/Johaden/article/details/141023668 一、旋转矩阵 1.点、向量、坐标系 在数学中&…...

计算机毕业设计选题推荐-二手图书交易系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

4.MySQL数据类型

目录 数据类型 ​编辑数值类型 tinyint类型 bit类型 float类型 decimal类型 字符串类型 char类型 varchar varchar和char的区别 日期和时间类型 数据类型 数值类型 说明一下&#xff1a;MySQL本身是不支持bool类型的&#xff0c;当把一个数据设置成bool类型时&#x…...

快递查询新纪元:一键批量获取多家快递物流详情

跨快递平台批量查询神器&#xff1a;一站式解决信息追踪难题——固乔快递查询助手 在电商行业日益繁荣的今天&#xff0c;快递服务已经成为连接买卖双方不可或缺的一环。然而&#xff0c;随着合作的快递公司日益增多&#xff0c;如何高效地管理和追踪不同平台的快递信息&#…...

docker部署redis和mongoDB

docker部署mongoDB redismongoDB redis # --requirepass指定redis连接时的密码 # --appendonly yes 开启reids的AOF功能 docker run --name redis -p 6379:6379 -d redis:5.0.14 redis-server --requirepass 1234 --appendonly yes# 以/etc/redis/redis.conf的配置信息启动red…...

了解LVS,配置LVS

项目一、LVS 1.集群Cluster Cluster: 集群是为了解决某个特定问题将堕胎计算机组合起来形成的单个系统 LB&#xff1a;负载均衡 HA&#xff1a;高可用 HPC&#xff1a;高性能计算 2.分布式 分布式是将一个请求分成三个部分&#xff0c;按照功能拆分&#xff0c;使用微服…...

目标检测综述文章解读——Object Detection in 20 Years: A Survey

论文&#xff1a;Object Detection in 20 Years: A Survey 作者&#xff1a;Zhengxia Zou, Keyan Chen, Zhenwei Shi, Yuhong Guo, Jieping Ye 链接&#xff1a;https://arxiv.org/abs/1905.05055 这是一篇关于目标检测综述性文章&#xff0c;自2019年5月第一次提交后&#xff…...

Android make_vbmeta_image的参数值定义

网上生成vbmeta_system.img的命令,分析下这些参数的赋值,key的路径 out/host/linux-x86/bin/avbtool make_vbmeta_image --algorithm SHA256_RSA2048 --key device/mediatek/system/common/key/rsa2048/oem_prvk.pem --padding_size 4096 --rollback_index 0 --...

代码规范 —— 并发编程规范

优质博文&#xff1a;IT-BLOG-CN 【1】【强制】获取单例对象需要保证线程安全&#xff0c;其中的方法也要保证线程安全。 说明&#xff1a; 资源驱动类、工具类、单例工厂类都需要注意。 【2】【强制】创建线程或线程池时请指定有意义的线程名称&#xff0c;方便出错时回溯。…...

仪器仪表控制:pymeasure常用模块以及API

下面是对 pymeasure.experiment 模块中各类和方法的详细介绍&#xff0c;包括它们的功能和用法。 pymeasure.experiment 模块详细介绍 Experiment 类 Experiment 类是 Pymeasure 中用于定义和管理实验的核心类。它包含实验的设置、执行和数据记录等功能。 构造函数 class …...

如何理解openfoam案例里面的blockMesh文件里面的simpleGrading

总结&#xff1a; simpleGrading参数分为xyz三个方向。如果你想使得网格在某个方向上更密集&#xff0c;可以在simpleGrading中将该方向的渐变率设置为小于 1 .更稀疏则设置大于1. 一、案例 比如我这个爆炸案例&#xff1a; 对应的blockMeshDIct文件如下&#xff1a; // 定…...

算法竞赛的制胜法宝:被严重低估的位运算究竟有什么用?

大家好&#xff0c;我是干货哥。今天咱们来聊聊一个让很多人都忽略的神技——位运算。等等&#xff0c;你是不是已经准备关掉这篇文章了&#xff1f;你以为位运算只是计算机底层的鸡肋操作&#xff1f;你以为这些不过是编程语言里最基础、最无趣的东西&#xff1f;但真的是这样…...

Qt QTableWidget 去除序号列

ui->tableWidget->verticalHeader()->setHidden(true);//垂直序列号&#xff08;表左侧&#xff09;ui.tableWidget->horizontalHeader()->setHidden(true);//水平序列号&#xff08;表上方&#xff09;删除后效果图&#xff1a;...

【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;可以为企业带来深…...