【C++】类和对象——拷贝构造函数、运算符重载、日期类实现、const成员、取地址操作符重载

news2024/11/18 7:38:39

目录

    • 拷贝构造函数
    • 运算符重载
    • 日期类实现
    • const成员
    • 取地址及const取地址操作符重载

拷贝构造函数

拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。

拷贝构造函数也是特殊的成员函数,其特征如下:

1、 拷贝构造函数是构造函数的一个重载形式。
2、 拷贝构造函数的参数只有一个且必须是同类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date(Date& d)//拷贝构造函数要加引用
	{
		cout << "Date(Date& d)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void print()
	{
		cout << _year << "/" << _month << "/" << _day << "/" << endl;
	}
private:
	int _year = 1;
	int _month;
	int _day;

};
void func1(Date d2)
{

}
int main()
{
	Date d1;
	//以下两种写法都是拷贝构造
	Date d2(d1);
	func1(d2);
	Date d3 = d1;
	
	return 0;
}

C++中规定,传值和传参都要调用拷贝构造函数,C++中不能像C语言一样直接进行传递,自定义类型传值传参必须要调用拷贝构造函数。

在这里插入图片描述

typedef int DataType;
class Stack
{
public:
	//构造函数进行初始化
	Stack(size_t capacity = 3)
	{
		cout << "Stack(size_t capacity = 3)" << endl;
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		if (_array == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		_capacity = capacity;
		_size = 0;
	}
	//拷贝构造函数 ——深拷贝
	Stack(Stack& s)
	{
		cout << "Stack(Stack& s)" << endl;
		_array = (DataType*)malloc(sizeof(DataType) * s._capacity);
		if (_array == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		memcpy(_array, s._array, sizeof(DataType) * s._size);
		_size = s._size;
		_capacity = s._capacity;
	}
	void Push(int data)
	{
		_array[_size] = data;
		_size++;
	}
	~Stack()
	{
		cout << "~Stack()" << endl;
		free(_array);
		_array = nullptr;
		_size = 0;
		_capacity = 0;
	}
private:
	DataType* _array;
	int _size;
	int _capacity;
};
int main()
{
	Stack s1;
	Stack s2 = s1;//调用拷贝构造
	//析构两次
	return 0;
}

在这里插入图片描述

3、若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。

内置类型:值拷贝

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//Date(const Date& d)//拷贝构造函数要加引用
	//{
	//	cout << "Date(Date& d)" << endl;
	//	_year = d._year;
	//	_month = d._month;
	//	_day = d._day;
	//}
	void print()
	{
		cout << _year << "/" << _month << "/" << _day << "/" << endl;
	}
private:
	int _year = 1;
	int _month;
	int _day;

};
int main()
{
	Date d1;
	Date d2 = d1;

	return 0;
}

自定义类型:调用他的拷贝构造函数

typedef int DataType;
class Stack
{
public:
	//构造函数进行初始化
	Stack(size_t capacity = 3)
	{
		cout << "Stack(size_t capacity = 3)" << endl;
		_array = (DataType*)malloc(sizeof(DataType) * capacity);
		if (_array == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		_capacity = capacity;
		_size = 0;
	}
	//拷贝构造函数 ——深拷贝
	Stack(const Stack& s)
	{
		cout << "Stack(Stack& s)" << endl;
		_array = (DataType*)malloc(sizeof(DataType) * s._capacity);
		if (_array == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		memcpy(_array, s._array, sizeof(DataType) * s._size);
		_size = s._size;
		_capacity = s._capacity;
	}
	void Push(int data)
	{
		_array[_size] = data;
		_size++;
	}
	~Stack()
	{
		cout << "~Stack()" << endl;
		free(_array);
		_array = nullptr;
		_size = 0;
		_capacity = 0;
	}
private:
	DataType* _array;
	int _size;
	int _capacity;
};
int main()
{
	Stack s1;
	Stack s2 = s1;//调用拷贝构造
	//析构两次
	return 0;
}

总结:Date不需要我们实现拷贝构造,默认生成就可以用
Stack需要我们自己实现深拷贝的拷贝构造,默认生成会出现问题

默认生成的构造和析构函数:
1、内置类型不做处理
2、自定义类型调用默认构造和析构函数
默认生成拷贝和赋值重载函数:
1、内置类型值拷贝 (浅拷贝)
2、自定义类型调用拷贝构造赋值重载函数

运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号
函数原型:返回值类型 operator操作符(参数列表)

注意:
1、不能通过连接其他符号来创建新的操作符:比如operator@
2、重载操作符必须有一个类类型的参数(自定义类型的参数)
3、用于内置类型的运算符,其含义不能改变,例如内置的整型+,不能改变其含义
4、作为类成员函数重载时,其形参看起来比操作数数目少1,是因为成员函数的第一个参数为隐藏的this
5、. * : : sizeof ?: . 以上5个运算符不能够发生重载。
6、不能改变操作符的操作数个数,一个操作符是几个操作数,那么重载的时候就有几个参数。

重载<运算符

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date(Date& d)//拷贝构造函数要加引用
	{
		cout << "Date(Date& d)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void print()
	{
		cout << _year << "/" << _month << "/" << _day << "/" << endl;
	}

	//d1<d2
	//d1.operator<(d2)
	bool 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;
		}
		else
		{
			return false;
		}
	}
private:
	int _year = 1;
	int _month;
	int _day;

};

 //运算符重载

int main()
{
	Date d1(2023, 7, 21);
	Date d2(2022, 8, 21);
	//d1 < d2;
	cout << (d1 < d2) << endl;
	cout << d1.operator<(d2) << endl;
}
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	
	void print()
	{
		cout << _year << "/" << _month << "/" << _day << "/" << endl;
	}

	//d1<d2
	//d1.operator<(d2)
	bool 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;
		}
		else
		{
			return false;
		}
	}
	bool operator==(const Date& d)
	{
		return _year == d._year && _month == d._month && _day == d._day;
	}
	//d1<=d2
	//this就是d1的地址
	bool operator<=(const Date& d)
	{
		return *this < d || *this == d;
	}

	bool operator>=(const Date& d)
	{
		return !(*this < d);
	}
	bool operator>(const Date& d)
	{
		return !(*this <= d);
	}
	bool operator!=(const Date& d)
	{
		return !(*this == d);
	}

	int GetMonthDay(int year, int month)
	{
		int monthArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		//如果是2月才去判断闰年
		if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
		{
			return 29;
		}
		return monthArray[month];
	}

	//出了作用域对象还在可以用引用返回
	Date& operator+=(int day)
	{
		_day += day;
		while (_day > GetMonthDay(_year, _month))
		{
			//月进位
			_day -= GetMonthDay(_year, _month);
			_month++;

			//月满了
			if (_month == 13)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

	//出了作用域对象不在了,不能用引用返回
	Date operator+(int day)
	{
		Date tmp(*this);
		tmp += day;
		return tmp;
		//while (tmp._day > GetMonthDay(tmp._year, tmp._month))
		//{
		//	//月进位
		//	tmp._day -= GetMonthDay(tmp._year, tmp._month);
		//	tmp._month++;

		//	//月满了
		//	if (tmp._month == 13)
		//	{
		//		tmp._year++;
		//		tmp._month = 1;
		//	}
		//}
	
	}
private:
	int _year = 1;
	int _month;
	int _day;

};

 //运算符重载

int main()
{
	Date d1(2023, 7, 21);
	Date d2(2022, 8, 21);
	//d1 < d2;
	cout << (d1 < d2) << endl;
	cout << d1.operator<(d2) << endl;

	cout << (d1 == d2) << endl;


	//Date ret = d1 += 100;//拷贝构造,返回值
	//ret.print();
	//d1.print();


	Date ret = d1 + 100;
	ret.print();
	d1.print();
	return 0;
}

日期类实现

日期类实现采用声明和定义分离的方式
Date.h文件中存放声明
Date.cpp中存放成员函数的实现

在日期类中如果使用全缺省参数的形式提供构造函数,那么在Date.h中给全缺省参数,Date.cpp中不给

在这里插入图片描述
在这里插入图片描述
认清拷贝构造和赋值的区别:
拷贝构造:一个已经存在的对象去初始化另一个要创建的对象。

int main()
{

	Date d1(2023, 7, 31);
	Date d2(d1);
	return 0;
}

赋值:两个已经存在的对象进行拷贝

int main()
{

	Date d1(2023, 7, 31);
	Date d2(2023, 4, 2);
	d1 = d2;
	return 0;
}

运算符重载,前置++和后置++
前置++:

//++d1  -> d1.operator++()
	Date operator++()
	{

	}

后置++:

//d1++  -> d1.operator++(0)
	Date operator++(int)
	{

	}

1、前置++运算符重载和后置++运算符重载构成了函数重载
2、为了区分前置++和后置++,在后置++中加一个int参数进行占位
3、前置++和后置++两者本质,后置++调用,编译器进行特殊处理

日期类实现:
Date.h文件:

#pragma once
#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1);
	void Print();
	int GetMonthDay(int year, int month);
	//赋值运算符重载
	Date& operator=(const Date& d);
	bool operator<(const Date& d);
	bool operator==(const Date& d);
	//d1<=d2
	//this就是d1的地址
	bool operator<=(const Date& d);

	bool operator>=(const Date& d);
	bool operator>(const Date& d);
	bool operator!=(const Date& d);
	

	//出了作用域对象还在可以用引用返回
	Date& operator+=(int day);
	//出了作用域对象不在了,不能用引用返回
	Date operator+(int day);

	//出了作用域对象还在可以用引用返回
	Date& operator-=(int day);
	//出了作用域对象不在了,不能用引用返回
	Date operator-(int day);

	//++d1  -> d1.operator++()
	Date& operator++();


    //d1++  -> d1.operator++(0)
	Date operator++(int);

	Date& operator--();
	Date operator--(int);

	//计算两个日期之间差多少天
	int operator-(const Date& d);

private:
	int _year;
	int _month;
	int _day;
};

Date.cpp文件:

#include "Date.h"

//构造函数要对日期进行相应的检查,避免有不存在的时间
Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;

	//检查日期是否合法
	if (month < 1 || month>12
		|| day<1 || day>GetMonthDay(year, month))
	{
		cout << "非法日期" << endl;
		//exit(-1);
	}
}

void Date::Print()
{
	cout << _year << "年" << _month << "月" << _day << "日" << endl;
}
int Date:: GetMonthDay(int year, int month)
{
	//加static,因为该函数避免不了重复调用,减少开销
	static int monthArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	//如果是2月才去判断闰年
	if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
	{
		return 29;
	}
	return monthArray[month];
}
Date& Date:: operator=(const Date& d)
{
	if (this != &d)
	{
		this->_year = d._year;
		this->_month = d._month;
		this->_day = d._day;
	}
	return *this;//this出了作用域还在,所以用引用返回
}
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;
	}
	else
	{
		return false;
	}
}
bool Date::operator==(const Date& d)
{
	return _year == d._year && _month == d._month && _day == d._day;
}
//d1<=d2
//this就是d1的地址
bool Date:: operator<=(const Date& d)
{
	return *this < d || *this == d;
}

bool Date:: operator>=(const Date& d)
{
	return !(*this < d);
}
bool Date:: operator>(const Date& d)
{
	return !(*this <= d);
}
bool Date:: operator!=(const Date& d)
{
	return !(*this == d);
}



//1、
//出了作用域对象还在可以用引用返回
Date& Date:: operator+=(int day)//自己改变
{
	if (day < 0)
	{
		return *this -= (-day);
	}
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		//月进位
		_day -= GetMonthDay(_year, _month);
		_month++;

		//月满了
		if (_month == 13)
		{
			_year++;
			_month = 1;
		}
	}
	return *this;
}

//出了作用域对象不在了,不能用引用返回
Date Date:: operator+(int day)//自己不改变
{
	Date tmp(*this);//拷贝构造
	tmp += day;
	return tmp;
	//while (tmp._day > GetMonthDay(tmp._year, tmp._month))
	//{
	//	//月进位
	//	tmp._day -= GetMonthDay(tmp._year, tmp._month);
	//	tmp._month++;

	//	//月满了
	//	if (tmp._month == 13)
	//	{
	//		tmp._year++;
	//		tmp._month = 1;
	//	}
	//}

}



//2、效率上不好
//出了作用域对象还在可以用引用返回
//Date& Date:: operator+=(int day)//自己改变
//{
//	*this = *this + day;
//	
//	return *this;
//}
//
出了作用域对象不在了,不能用引用返回
//Date Date:: operator+(int day)//自己不改变
//{
//	Date tmp(*this);//拷贝构造
//	tmp._day += day;
//	//return tmp;
//	while (tmp._day > GetMonthDay(tmp._year, tmp._month))
//	{
//		//月进位
//		tmp._day -= GetMonthDay(tmp._year, tmp._month);
//		tmp._month++;
//
//		//月满了
//		if (tmp._month == 13)
//		{
//			tmp._year++;
//			tmp._month = 1;
//		}
//	}
//	return tmp;
//
//}

//出了作用域对象还在可以用引用返回
Date& Date:: operator-=(int day)//无拷贝
{
	if (day < 0)
	{
		return *this += (-day);
	}
	_day -= day;
	while (_day <= 0)
	{
		_month--;
		if (_month == 0)
		{
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}
//出了作用域对象不在了,不能用引用返回
Date Date:: operator-(int day)
{
	Date tmp(*this);
	tmp -= day;
	return tmp;
}


//++d1  -> d1.operator++()
Date& Date:: operator++()
{
	*this += 1;
	return *this;
}


//d1++  -> d1.operator++(0)
Date Date:: operator++(int)
{
	Date tmp(*this);
	*this += 1;
	return tmp;
}


Date& Date:: operator--()
{
	*this -= 1;
	return *this;
}
Date Date:: operator--(int)
{
	Date tmp(*this);
	*this -= 1;
	return tmp;
}

//计算两个日期之间差多少天
//d1 - d2
int Date:: operator-(const Date& d)
{
	Date max = *this;
	Date min = d;   //假设
	int flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	int n = 0;
	while (min != max)
	{
		min++;
		n++;
	}
	return n * flag;
}

test.cpp文件:

#include "Date.h"
void TestDate1()
{
	Date d1(2023, 8, 1);
	Date d2;

	d1.Print();
	d2.Print();

	Date d3(2023, 2, 29);
	d3.Print();
}
void TestDate2()
{
	Date d1(2023, 8, 6);
	Date d2(2023, 8, 13);
	Date d3(2023, 8, 13);
	//d1 = d2 = d3;
	d1 += 100;
	d1.Print();
	//拷贝构造
	Date ret = d2 + 200;//也是拷贝构造
	ret.Print();

	//赋值
	/*Date ret;
	ret = d2 + 100;*/


	//Date ret1 = d1;//虽然有赋值,但其实是拷贝构造
	//Date ret(d2 + 100);


}
void TestDate3()
{
	Date d1(2023, 4, 3);
	Date ret = d1 + 100;
	ret.Print();
}
void TestDate4()
{
	Date d1(2023, 7, 27);
	d1 -= 2000;
	d1.Print();

	Date d2(2023, 7, 27);
	d2 += -200;
	d2.Print();

	Date d3(2023, 7, 27);
	d3 -= -200;
	d3.Print();
}

//int main()
//{
//
//	Date d1(2023, 7, 31);
//	Date d2(2023, 4, 2);
//	d1 = d2;
//	return 0;
//}

void TestDate5()
{
	Date d1(2023, 7, 27);
	//Date ret1 = d1++; //后置++返回++之前的值,之后自己变成++之后的值
	Date ret1 = d1.operator++(0);
	ret1.Print();
	d1.Print();
	

	//Date ret2 = ++d1;
	Date ret2 = d1.operator++();
	ret2.Print();//前置++返回++之后的值,自己也是++之后的值
	d1.Print();
}
void TestDate6()
{
	Date d1(2023, 7, 27);
	Date d3(2023, 10, 1);
	cout << d3 - d1 << endl;
}
int main()
{

	//TestDate1();
	//TestDate2();
	//TestDate3();
	TestDate6();
	return 0;
}

const成员

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针表明在该成员函数中不能对类的任何成员进行修改

在这里插入图片描述
修改:
在这里插入图片描述

在这里插入图片描述

void TestDate7()
{
    // 权限平移
	const Date d1(2023, 8, 2);
	d1.Print();
	
	//权限缩小
	Date d2(2023, 4, 2);
	d2.Print();
}
void Date::Print() const
{
	cout << _year << "年" << _month << "月" << _day << "日" << endl;
}
  1. const对象可以调用非const成员函数吗?不能
  2. 非const对象可以调用const成员函数吗?可以
  3. const成员函数内可以调用其它的非const成员函数吗?不能
  4. 非const成员函数内可以调用其它的const成员函数吗?可以

两个函数构成函数重载,一个函数只读,另一个函数只写(或读)


#include <iostream>
#include <assert.h>
using namespace std;
struct SeqList
{
public:
	void PushBack(int x)
	{
		_a[_size++] = x;
	}
	size_t size() const
	{
		return _size;
	}
	const int& operator[](size_t i) const//读
	{                             //函数重载
		assert(i < _size);
		return _a[i];
	}
	int& operator[](size_t i)//可进行s[i]++(写)/读
	{
		assert(i < _size);
		return _a[i];
	}
private:
	int* _a = (int*)malloc(sizeof(int) * 10);
	size_t _size = 0;
	size_t _capacity = 0;
};
void Print(const SeqList& s)
{
	for (size_t i = 0; i < s.size(); i++)
	{
		//s[i]++;
		cout << s[i] << " ";
		//cout << s.operator[](i) << " ";

	}
	cout << endl;
}
int main()
{
	SeqList s;
	s.PushBack(1);
	s.PushBack(2);
	s.PushBack(3);
	s.PushBack(4);

	Print(s);
	for (size_t i = 0; i < s.size(); i++)
	{
		s[i]++;
	}
	Print(s);

	
	cout << endl;
	return 0;
}

哪些成员函数加const最好?
只读函数可以加const,内部不涉及修改成员的(本身不被修改的)都可以加const

取地址及const取地址操作符重载

这两个默认成员函数一般不用重新定义 ,编译器默认会生成。

class Date
{
public :
	Date(int year=1,int month = 1,int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}


	//取地址&重载有两个版本
	Date* operator&()
	{
		return this;
	}
	const Date* operator&() const
	{
		return this;
	}


private:
	int _year;
	int _month;
	int _day;

};
int main()
{
	Date d1(2023, 2, 3);
	cout << &d1 << endl;
	return 0;
}

这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如不想让别人获取到指定的内容!

1、普通对象和const修饰的对象都不想让别人获取到地址

Date* operator&()
	{
		return nullptr;
	}
	const Date* operator&() const
	{
		return nullptr;
	}

2、普通对象可以获取到地址,const修饰的对象不想让别人获取到地址

Date* operator&()
	{
		return this;
	}
	const Date* operator&() const
	{
		return nullptr;
	}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/826723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SOLIDWORKS 钣金零件怎么画?

一、SOLIDWORKS 钣金功能介绍 SOLIDWORKS 是一款广泛应用于机械设计领域的 CAD 软件&#xff0c;其钣金功能可以帮助用户快速创建钣金件的 3D 模型。钣金折弯是一种常见的加工方式&#xff0c;可以将平面材料通过弯曲变形成为所需形状。 二、如何使用 SOLIDWORKS 钣金功能 步骤…

shell清理redis模糊匹配的多个key

#!/bin/bash# 定义Redis服务器地址和端口 REDIS_HOST"localhost" REDIS_PORT6380# 获取匹配键的数量 function get_matching_keys() {local key_pattern"$1"redis-cli -h $REDIS_HOST -p $REDIS_PORT -n 0 KEYS "$key_pattern" }# 删除匹配的键 …

一文带你详细了解Open API设计规范

写在前面&#xff1a; OpenAPI 规范&#xff08;OAS&#xff09;定义了一个标准的、语言无关的 RESTful API 接口规范&#xff0c;它可以同时允许开发人员和操作系统查看并理解某个服务的功能&#xff0c;而无需访问源代码&#xff0c;文档或网络流量检查&#xff08;既方便人…

Atlas200DK A2联网实战

文章目录 1.Atlas原始网络信息2. 开发板联网2.1 使用Type-c 连接开发板2.2 修改本地网络适配器2.3 修改开发板网络信息2.4 测试外网连接 1.Atlas原始网络信息 Type-C 网口 ETH0 网口 ETH1 网口 2. 开发板联网 2.1 使用Type-c 连接开发板 使用xshell 等ssh终端登录开发板&…

【C++从0到王者】第十五站:list源码分析及手把手教你写一个list

文章目录 一、list源码分析1.分析构造函数2.分析尾插等 二、手把手教你写一个list1.结点声明2.list类的成员变量3.list类的默认构造函数4.list类的尾插5.结点的默认构造函数6.list类的迭代器7.设计const迭代器8.list的insert、erase等接口9.size10.list的clear11.list的析构函数…

【java安全】CommonsBeanUtils1

文章目录 【java安全】CommonsBeanUtils1前言Apache Commons BeanutilsBeanComparator如何调用BeanComparator#compare()方法&#xff1f;构造POC完整POC 调用链 【java安全】CommonsBeanUtils1 前言 在之前我们学习了java.util.PriorityQueue&#xff0c;它是java中的一个优…

2.2 身份鉴别与访问控制

数据参考&#xff1a;CISP官方 目录 身份鉴别基础基于实体所知的鉴别基于实体所有的鉴别基于实体特征的鉴别访问控制基础访问控制模型 一、身份鉴别基础 1、身份鉴别的概念 标识 实体身份的一种计算机表达每个实体与计算机内部的一个身份表达绑定信息系统在执行操作时&a…

3、详解桶排序及排序内容总结

堆 满二叉树可以用一个数组中从0开始的连续一段来记录 i i i位置左孩子: 2 ∗ i + 1 2*i+1 2∗i+1,右孩子: 2 ∗ i + 2 2*i+2 2∗i+2,父: ( i − 1 ) / 2 (i-1)/2 (i−1)/2 大根堆 每一棵子树的根为最大值 小根堆 每一棵子树的根为最小值 建大根堆 不断地根据公…

配置HDFS单机版,打造数据存储的强大解决方案

目录 简介&#xff1a;步骤&#xff1a;安装java下载安装hadoop配置hadoop-env.sh配置 core-site.xml配置hdfs-site.xml初始化hdfs文件系统启动hdfs服务验证hdfs 结论&#xff1a; 简介&#xff1a; Hadoop分布式文件系统&#xff08;HDFS&#xff09;是Hadoop生态系统中的一个…

【硬件设计】模拟电子基础二--放大电路

模拟电子基础二--放大电路 一、基本放大电路1.1 初始电路1.2 静态工作点1.3 分压偏置电路 二、负反馈放大电路三、直流稳压电路 前言&#xff1a;本章为知识的简单复习&#xff0c;适合于硬件设计学习前的知识回顾&#xff0c;不适合运用于考试。 一、基本放大电路 1.1 初始电…

数学建模-爬虫入门

Python快速入门 简单易懂Python入门 爬虫流程 获取网页内容&#xff1a;HTTP请求解析网页内容&#xff1a;Requst库、HTML结果、Beautiful Soup库储存和分析数据 什么是HTTP请求和响应 如何用Python Requests发送请求 下载pip macos系统下载&#xff1a;pip3 install req…

VactorCast自动化单元测试

VectorCAST软件自动化测试方案 VectorCAST软件自动化测试方案 博客园 软件测试面临的问题 有一句格言是这样说的&#xff0c;“如果没有事先做好准备&#xff0c;就意味着做好了 失败的准备。”如果把这个隐喻应用在软件测试方面&#xff0c;就可以这样说“没有测试到&#xf…

Tomcat虚拟主机

Tomcat虚拟主机 部署 [rootlocalhost webapps]# cd ../conf [rootlocalhost conf]# pwd /usr/local/tomcat/conf [rootlocalhost conf]# vim server.xml #增加虚拟主机配置&#xff0c;添加以下&#xff1a; <Host name"www.a.com" appBase"webapps"u…

react-redux的理解与使用

一、react-redux作用 和redux和flux功能一样都是管理各个组件的状态&#xff0c;是redux的升级版。 二、为什么要用reac-redux&#xff1f; 那么我们既然有了redux&#xff0c;为什么还要用react-redux呢&#xff1f;原因如下&#xff1a; 1&#xff0c;解决了每个组件用数…

怎么才能远程控制笔记本电脑?

为什么选择AnyViewer远程控制软件&#xff1f; 为什么AnyViewer是远程控制笔记本电脑软件的首选&#xff1f;以下是选择AnyViewer成为笔记本电脑远程控制软件的主要因素。 跨平台能力 AnyViewer作为一款跨平台远程控制软件&#xff0c;不仅可以用于从一台Windows电…

数据库监控平台,数据库监控的指标有哪些--PIGOSS BSM

引言 在现代企业的信息化时代&#xff0c;数据库作为关键的数据存储和管理工具&#xff0c;扮演着至关重要的角色。然而&#xff0c;数据库的稳定性和高效性对于企业的正常运营至关重要。为了帮助企业保障数据库的运行状态&#xff0c;我们公司推出了PIGOSS BSM&#xff0c;一款…

MySql006——基本的SELECT查询语句

在《MySql003——结构化查询语言SQL基础知识》中&#xff0c;我们学习了有关SQL的基础知识&#xff0c;也知道SQL中查询语句SELECT使用最为频繁 接下来我们将学习一些基本的SELECT查询语句 一、SELECT语句的通用语法 在MySQL数据库中&#xff0c;使用SELECT语句可以查询数据…

024 - mix()函数

定义&#xff1a;MIN()函数返回一组值中的最小值。NULL 值不包括在计算中。 语法&#xff1a; MIN(expression) 参数值&#xff1a; 参数 描述 expression 必须项。数值&#xff08;可以是字段或公式&#xff09; -- 实际操作&#xff08;查询最小工资数&#xff09;: SE…

绿盟认证概述

目录 1.前言 2.绿盟认证概述 1.前言 2020,沪漂上海,初入网安,干着安服,月薪8k,金牌代理,分享给大家。记得还拿下了绿盟的NCSA售后和售前的考证呢! 2.绿盟认证概述

【爬虫实践】使用Python从网站抓取数据

一、说明 本周我不得不为客户抓取一个网站。我意识到我做得如此自然和迅速&#xff0c;分享它会很有用&#xff0c;这样你也可以掌握这门艺术。【免责声明&#xff1a;本文展示了我的抓取做法&#xff0c;如果您有更多相关做法请在评论中分享】 二、计划策略 2.1 策划 确定您…