C++类与对象:默认成员函数

文章目录

  • 1.类的6个默认成员函数
  • 2.构造函数
  • 3.析构函数
  • 4. 拷贝构造函数
  • 5.赋值运算符和运算符重载
  • 6.日期类实现
  • 7.const成员
  • 8.重载流插入<< ,流提取>>
    • 1.流插入
    • 2.流提取
  • 9.取地址及const取地址操作符重载

1.类的6个默认成员函数

空类:也就是什么成员都没有的类。

但事实上,空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。

默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
在这里插入图片描述

2.构造函数

概念:

构造函数:创建类类型对象时由编译器自动调用,以保证每个数据成员都有一个合适的初始值,并且在对象整个生命周期内只调用一次

#include <iostream>
using namespace std;

class Date
{
public:
// 以下构造函数只能存在一个!!!
    // 无参默认构造函数
    Date()
    {
        _year = 1900;
        _month = 1;
        _day = 1;
    }
    // 全缺省默认构造函数
    Date(int year = 1900, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    // 编译器生成的默认构造函数


    // C++11补丁新增内置类型成员变量(int char double 指针....)在类中声明时可以给默认值,此处仍是声明不是定义!!!
private:
    int _year = 0;
    int _month = 0;
    int _day = 0;
};
// 以下测试函数能通过编译吗?
void Test()
{
    Date d1;
}
int main()
{
    Test();
    return 0;
}

在这里插入图片描述

特性:

  • 函数名与类名相同,无返回值类型
  • 对象实例化时编译器自动调用对应的构造函数
  • 构造函数可以重载。
  • 构造函数的并不是开辟空间创建对象,而是初始化对象
  • 如果类中没有显式定义构造函数,则编译器会自动生成一个无参的默认构造函数,而用户显式定义编译器将不再生成
  • 不实现构造函数的情况下,编译器会生成默认的构造函数,此默认构造函数对内置类型不起作用,只对自定义类型初始化
  • C++11中针对内置类型成员不初始化的缺陷,又打了补丁:内置类型成员变量在类中声明时可以给默认值。

3.析构函数

概念:

析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器在栈区上完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作,一般清理的是堆上malloc开辟出来的空间

  • 函数名是在类名前加上字符 ~,无参数,无返回值类型
  • 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数,析构函数不能重载
  • 对象生命周期结束时,C++编译系统系统自动调用析构函数
  • 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,有资源申请时,一定要写,否则会造成资源泄漏,比如Stack类需要动态开辟空间
#include <iostream>
using namespace std;

class stack
{
public:

	void Push(const int& data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}

	// 半缺省构造函数
	stack(int capacity = 10)
	{
		cout << "构造" << endl;
		_array = (int*)malloc(10 * sizeof(int));
		if (_array == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		_size = 0;
		_capacity = capacity;
	}

	// 析构函数
	~stack()
	{
		cout << "析构" << endl;
		free(_array);
		_array = NULL;
		_size = 0;
		_capacity = 0;
	}

	// 拷贝构造函数:深拷贝
	stack(const stack& st)
	{
		cout << "拷贝构造" << endl;

		_array = (int*)malloc(st._capacity * sizeof(int));
		if (_array == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		_size = st._size;
		_capacity = st._capacity;
	}
private:
	int* _array;
	int _size;
	int _capacity;

};

int main()
{
	stack st1;
	stack st2(st1);
	return 0;
}

在这里插入图片描述

4. 拷贝构造函数

概念:

拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰,防止原本对象被修改),在创建对象时,可以创建一个与已存在对象一某一样的新对象

特性:

  • 函数名是类名,无返回值类型,参数只有一个且必须是类对象的引用,使用传值方式编译器会报错,因为会引发无穷递归调用

  • 拷贝构造函数是构造函数的一个重载形式

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

  • 类中如果没有涉及资源申请时,拷贝构造函数写不写都可以,一旦涉及到资源申请时,则拷贝构造函数一定要写成深拷贝的,否则默认拷贝构造函数为浅拷贝

// 拷贝构造:浅拷贝
#include <iostream>
using namespace std;

class Date
{
public:
    ~Date()
    {
        cout << "~Data()" << endl;
    }
    Date(int year = 2024, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
        cout << "Data()" << endl;
    }
    /*
    拷贝构造函数:浅拷贝
    Date(const Date& d)
    {
        _year = d._year;
        _month = d._month;
        _day = d._day;
        cout << "Data(Date& d)" << endl;
    }
    */
private:
    int _year = 0;
    int _month = 0;
    int _day = 0;
};

int main()
{
    // c++规定自定义类型都会调用拷贝构造,传引用传参就不会调用拷贝构造了,否则会无限递归
    Date d1(2024,1,28);
    Date d2(d1);
    return 0;
}

在这里插入图片描述

#include <iostream>
using namespace std;

class stack
{
public:
    
	void Push(const int& data)
	{
		// CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	// 半缺省构造函数
	stack(int capacity = 10)
	{
		_array = (int*)malloc(10 * sizeof(int));
		if (_array == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		_size = 0;
		_capacity = capacity;
		cout << "构造" << endl;
	}

	// 析构函数
	~stack()
	{
		free(_array);
		_array = NULL;
		_size = 0;
		_capacity = 0;
	}

	// 拷贝构造函数:深拷贝
	stack(const stack& st)
	{
		_array = (int*)malloc(st._capacity * sizeof(int));
		if (_array == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		_size = st._size;
		_capacity = st._capacity;
	}

private:
	int* _array;
	int _size;
	int _capacity;

};

int main()
{
	stack st1;
	stack st2(st1);
	return 0;
}

在这里插入图片描述

5.赋值运算符和运算符重载

运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似

  • 重载操作符必须有一个类类型参数
  • 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义
  • 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this指针
  • .* :: sizeof ?: . 注意以上5个运算符不能重载

赋值运算符重载

  • 参数类型:const T&,传递引用可以提高传参效率
  • 返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
  • 检测是否自己给自己赋值
  • 返回*this :符合连续赋值的含义

赋值运算符只能重载成类的成员函数不能重载成全局函数?

  • 赋值运算符的左操作数是被赋值的对象本身,而右操作数是要赋给该对象的值。因此,赋值运算符的操作涉及到两个对象:被赋值对象和赋值对象。如果定义为全局函数,就需要两个参数,而如果定义为成员函数,就只需要一个参数,因为左操作数可以通过this指针访问。
  • 如果定义为全局函数,就可能出现二义性,因为编译器会为每个类隐式地定义一个赋值运算符。如果再定义一个全局的赋值运算符,就会导致编译器无法确定调用哪个函数。
  • 如果定义为全局函数,就可能破坏类的封装性,因为全局函数无法访问类的私有成员或静态成员。如果要访问这些成员,就需要将全局函数声明为类的友元函数,这样就会增加类的复杂性和耦合性。
  • 如果定义为全局函数,就可能导致语义不清,因为赋值运算符通常是类的内在行为,与类的具体实现密切相关。如果将赋值运算符定义为全局函数,就会使得类的实现细节暴露给外部,降低了类的抽象性和可维护性。

为什么运算符重载可以重载成全局函数呢?

  • 全局函数可以支持左操作数不是类对象的情况,例如可以将数字和向量对象相乘,而不仅仅是向量对象和数字相乘。
  • 全局函数可以避免重载运算符时的二义性,例如如果重载赋值运算符为全局函数,就不会与编译器隐式定义的赋值运算符冲突。
  • 全局函数可以提高运算符的灵活性和通用性,例如可以重载输入/输出运算符,使得可以用 cout 和 cin 来输出和输入类对象。
  • 全局函数可以保持运算符的对称性,例如如果重载加法运算符为全局函数,就可以同时支持 a+b 和 b+a 的形式,而不需要为每种情况都定义一个成员函数。

6.日期类实现

Date.h:

#pragma once
#include<assert.h>
#include<iostream>
using namespace std;

// 日期类实现
class Date
{
public:
	Date(int year = 2024, int month = 1, int day = 1);
	~Date();
	Date(const Date& d);	// 同类型对象进行初始化

	// 获取某年某月的天数
	int GetMonthDay(int year, int month) const	// 直接在类中定义相当于inline内联展开(此函数我们后续需要频繁调用)
	{
		assert(month > 0 && month < 13);
		static int monthday[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };// 数组放到静态区,增加程序效率
		// 1.四年一润百年不润 2.四百年一润
		if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
		{
			return 29;
		}
		return monthday[month];
	}
	/*
		将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,
		实际修饰该成员函数隐含的this指针指向的内容,表明在该成员函数中不能对类的任何成员进行修改
	*/
	void Print() const
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}

	/*
	1.	运算符重载成全局的就需要成员变量是公有的,问题来了,封装性如何保证?友元解决或者干脆重载成类的成员函数
	2.	赋值运算符只能重载成类的成员函数不能重载成全局函数
	*/
	bool operator==(const Date& d) const;
	bool operator>(const Date& d) const;
	bool operator >= (const Date& d) const;
	bool operator < (const Date& d) const;
	bool operator <= (const Date& d) const;
	bool operator != (const Date& d) const;

	Date operator=(const Date& d);
	Date operator+(int day) const;
	Date& operator+=(int day);
	Date operator-(int day) const;
	Date& operator-=(int day);

	// 前置++运算符重载
	Date& operator++();
	// 后置++运算符重载
	Date operator++(int);
	// 前置--运算符重载
	Date& operator--();
	// 后置--运算符重载
	Date operator--(int);

	// 流插入 << 重载:返回值目的为了支持连续性
	friend ostream& operator<<(ostream& out, const Date& d);
	// 流提取 >> 重载:返回值目的为了支持连续性
	friend istream& operator>>(istream& in, Date& d);


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

Date.cpp:

#include"Date.h"
// 声明和定义分离

// 构造函数
Date::Date(int year, int month, int day)
{
	this->_year = year;
	this->_month = month;
	this->_day = day;
}

// 深度拷贝构造函数
Date::Date(const Date& d)
{
	this->_year = d._year;
	this->_month = d._month;
	this->_day = d._day;
}

// 析构函数
Date::~Date()
{
	this->_year = 2024;
	this->_month = 1;
	this->_day = 1;
}

bool Date::operator==(const Date& d) const
{
	return _year == d._year && _month == d._month && _day == d._day;
}

bool Date::operator>(const Date& d) const
{
	if (_year > d._year)
	{
		return true;
	}
	else if (_year == d._year)
	{
		if (_month > d._month)
		{
			return true;
		}
		else if (_month == d._month)
		{
			if (_day > d._day)
			{
				return true;
			}
		}
	}
	return false;
}

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

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

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

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

Date Date::operator=(const Date& d)
{
	if (this != &d)
	{
		this->_year = d._year;
		this->_month = d._month;
		this->_day = d._day;
	}
	return *this;
}

Date Date::operator+(int day) const
{
	Date tmp = *this;// 赋值重载拷贝防止原来的日期被改变
	tmp._day = tmp._day + day;
	int monthday = Date::GetMonthDay(tmp._year, tmp._month);
	if (tmp._day <= monthday)
	{
		return tmp;
	}
	while (tmp._day > monthday)
	{
		monthday = Date::GetMonthDay(tmp._year, tmp._month);
		tmp._day = tmp._day - monthday;
		if (tmp._month < 12)
		{
			tmp._month++;
		}
		else
		{
			tmp._month = 1;
			tmp._year++;
		}
	}
	return tmp;
}

Date& Date::operator+=(int day)
{
	this->_day = this->_day + day;
	int monthday = Date::GetMonthDay(this->_year, this->_month);
	if (this->_day <= monthday)
	{
		return *this;
	}
	while (this->_day > monthday)
	{
		monthday = Date::GetMonthDay(this->_year, this->_month);
		this->_day = this->_day - monthday;
		if (this->_month < 12)
		{
			this->_month++;
		}
		else
		{
			this->_month = 1;
			this->_year++;
		}
	}
	return *this;
}

Date Date::operator-(int day) const
{
	Date tmp = *this;// 赋值重载拷贝防止原来的日期被改变
	tmp._day = tmp._day - day;
	int monthday = Date::GetMonthDay(tmp._year, tmp._month);
	if (tmp._day > 0)
	{
		return tmp;
	}
	while (tmp._day <= 0)
	{
		if (tmp._month == 1)
		{
			tmp._month = 12;
			tmp._year--;
		}
		else
		{
			tmp._month--;
		}
		monthday = Date::GetMonthDay(tmp._year, tmp._month);
		tmp._day = tmp._day + monthday;
	}
	return tmp;
}

Date& Date::operator-=(int day)
{
	this->_day = this->_day - day;
	int monthday = Date::GetMonthDay(this->_year, this->_month);
	if (this->_day > 0)
	{
		return *this;
	}
	while (this->_day <= 0)
	{
		if (this->_month == 1)
		{
			this->_month = 12;
			this->_year--;
		}
		else
		{
			this->_month--;
		}
		monthday = Date::GetMonthDay(this->_year, this->_month);
		this->_day = this->_day + monthday;
	}
	return *this;
}

// 前置++
Date& Date::operator++()
{
	this->_day++;
	int monthday = Date::GetMonthDay(this->_year, this->_month);
	if (this->_day > monthday)
	{
		this->_month++;
		this->_day = this->_day - monthday;
		if (this->_month > 12)
		{
			this->_month = 1;
			this->_year++;
		}
	}
	// 返回的是对象++后的全新的对象
	return *this;
}

// 后置++
Date Date::operator++(int)// 注意为何返回值区分了对象本身和对象的引用,在后置++中我们返回的是tmp这个局部变量因此只能返回局部对象的拷贝而不能返回引用
{
	Date tmp = *this;
	this->_day++;
	int monthday = Date::GetMonthDay(this->_year, this->_month);
	if (this->_day > monthday)
	{
		this->_month++;
		this->_day = this->_day - monthday;
		if (this->_month > 12)
		{
			this->_month = 1;
			this->_year++;
		}
	}
	//返回的是对象++之前的对象的拷贝
	return tmp;
}

// 前置--
Date& Date::operator--()
{
	this->_day--;
	if (this->_day > 0)
	{
		return *this;
	}
	else
	{
		this->_month--;
		if (this->_month == 0)
		{
			this->_month = 12;
			this->_year--;
		}
		int monthday = Date::GetMonthDay(this->_year, this->_month);
		this->_day = this->_day + monthday;
		return *this;
	}
}

// 后置--
Date Date::operator--(int)
{
	Date tmp = *this;
	this->_day--;
	if (this->_day > 0)
	{
		return tmp;
	}
	else
	{
		this->_month--;
		if (this->_month == 0)
		{
			this->_month = 12;
			this->_year--;
		}
		int monthday = Date::GetMonthDay(this->_year, this->_month);
		this->_day = this->_day + monthday;
		return tmp;
	}
}

// 友元函数
//
// 流插入 << 重载
ostream& operator<<(ostream& out, const Date& d)
{
	cout << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}
// 流提取 >> 重载
istream& operator>>(istream& in, Date& d)
{
	cout << "请依次输入年月日:" << endl;
	in >> d._year >> d._month >> d._day;
}

7.const成员

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

读函数:建议加const

写函数:谨慎加const

// 读函数
void Print() const
{
	cout << _year << '-' << _month << '-' << _day << endl;
}

// 写函数
// 构造函数
Date::Date(int year, int month, int day) const //错误const加入
{
	this->_year = year;
	this->_month = month;
	this->_day = day;
}
  1. [const对象不能调用非const成员函数,因为这样会破坏const对象的不可变性,或者导致类型不匹配的错误。如果非要调用非const成员函数,就需要使用const_cast来强制去除const限定]。
  2. [非const对象可以调用const成员函数,因为这样不会改变非const对象的状态,或者导致类型不匹配的错误。非const对象可以隐式转换为const对象,从而调用const成员函数]。
  3. [const成员函数不能调用其它的非const成员函数,因为这样会破坏const成员函数的不可变性,或者导致类型不匹配的错误。如果非要调用非const成员函数,就需要对this指针使用const_cast来强制去除const限定]。
  4. [非const成员函数可以调用其它的const成员函数,因为这样不会改变非const成员函数的状态,或者导致类型不匹配的错误。非const成员函数可以隐式转换为const成员函数,从而调用const成员函数]。

总之,const的调用满足权限可以缩小但不可以放大,也就是说非const修饰的对象或函数可以调用const修饰的对象或函数,但const修饰的对象或函数不可以调用非const修饰的对象或函数。

8.重载流插入<< ,流提取>>

1.流插入

这样写ok么?

// 日期类实现
class Date
{
public:
	Date(int year = 2024, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;
    }
    //流插入<<重载成为成员函数
    void operator<<(ostream& out)
	{
	cout << this->_year << "年" << this->_month << "月" << this->_day << "日" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024,2,1);
    //错误运行;
    cout<<d1;//cout作为左操作数,d1作为右操作数,d1日期类对象插入到控制台cout中去符合思维,但实际报错
    
    //正确运行:
	d1<<cout;//d1作为左操作数,cout作为右操作数,重载成功但是发现逻辑是控制台cout插入到日期类d1中
	return 0;
}

本质原因是什么呢?

解释:

<< 作为成员函数重载,this指针占据了第一个参数,意味着日期类(Date)对象必须是左操作数,因此我们要设法让cout作为第一个参数,因此为了实现这个操作符重载,我们不能将它写为成员函数,应当写为全局函数但是当我们将函数写成全局函数后面临它无法访问私有,因此此处我们要么私有公开为公有,要么使用友元,并且注意全局函数不能在.h头文件中定义,否则链接时候会发生重定义

在这里插入图片描述

第一种方式:

// 流输出 << 重载为全局函数,并且将类对象成员私有公开
void operator<<(ostream& out,const Date& d)
{
	cout << d._year << "年" << d._month << "月" << d._day << "日" << endl;
}

在这里插入图片描述

第二种方式:

设置Get,Set函数获取私有成员的值(不想破坏封装,可以替换掉友元)

第三种方式:

友元函数

friend void operator<<(ostream& out, const Date& d);

在这里插入图片描述

问题来了:我们实现的流插入如何支持连续插入呢?cout<<......<<......<<.......<<endl;

与赋值类似,不过结合性顺序相反:

cout<<d1<<d2<<;cout<<d1为一次函数调用,并且带有一个返回值作为左操作数再次进行流插入。

流插入:

friend ostream& operator<<(ostream& out, const Date& d);

ostream& operator<<(ostream& out, const Date& d)
{
	cout << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}

为什么C++要支持流插入和自定义重载流插入呢?因为C语言中的printf函数无法支持自定义类型直接通过printf输出,而流插入就很好的解决了所有对象的打印问题,无论是内置类型还是自定义类型。

2.流提取

流提取:

friend istream& operator>>(istream& in, Date& d);
istream& operator>>(istream& in, Date& d)
{
	cout << "请依次输入年月日:" << endl;
	in >> d._year >> d._month >> d._day;
}

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

这两个运算符一般不需要重载,直接取得对象的地址即可,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,一般不需要自己重写

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【AG32VF407】国产MCU+FPGA,更新官方固件解决8Mhz内部晶振不准,Verilog实测7.9Mhz!

视频讲解 [AG32VF407]国产MCUFPGA&#xff0c;更新官方固件解决8Mhz内部晶振不准&#xff0c;Verilog实测7.9Mhz&#xff01; 实验过程 之前出现的双路pll不同频率的测试中&#xff0c;提出了内部晶振输出不准的问题&#xff0c;和官方沟通后得到极大改善&#xff0c;方法如下…

基于SSM+MySQL的的新闻发布系统设计与实现

目录 项目简介 项目技术栈 项目运行环境 项目截图 代码截取 源码获取 项目简介 新闻发布系统是一款基于Servletjspjdbc的网站应用程序&#xff0c;旨在提供一个全面且高效的新闻发布平台。该系统主要包括后台管理和前台新闻展示两个平台&#xff0c;涵盖了新闻稿件的撰写…

ElasticSearch-IK分词器(elasticsearch插件)安装配置和ElasticSearch的Rest命令测试

四、IK分词器(elasticsearch插件) IK分词器&#xff1a;中文分词器 分词&#xff1a;即把一段中文或者别的划分成一个个的关键字&#xff0c;我们在搜索时候会把自己的信息进行分词&#xff0c;会把数据库中或者索引库中的数据进行分词&#xff0c;然后进行一一个匹配操作&…

四、CPU架构介绍和分类

中央处理器&#xff08;central processing unit&#xff0c;简称CPU&#xff09;作为计算机系统的运算和控制核心&#xff0c;是信息处理、程序运行的最终执行单元 1、CPU架构 CPU架构是CPU厂商给属于同一系列的CPU产品定的一个制作规范&#xff0c;主要目的是为了作为区分不同…

菜鸡后端的前端学习记录-2

前言 记录一下看视频学习前端的的一些笔记&#xff0c;以前对Html、Js、CSS有一定的基础&#xff08;都认得&#xff0c;没用过&#xff09;&#xff0c;现在不想从头再来了&#xff0c;学学Vue框架&#xff0c;不定时更新&#xff0c;指不定什么时候就鸽了。。。。 忘了记一下…

软件测试Bug系列之4个基本步骤(一)

目录 1.发现bug 2.提交bug 3.跟踪bug 4.总结bug 只要你一个测试人员 &#xff0c;就肯定离不开提交bug&#xff0c;跟踪bug的工作 。对于大多数的功能测试人员来说 &#xff0c;占比最多的工作就是和bug打交道 。可以说它是我们最重要的一块业绩 。所以&#xff0c;有必要静…

Maya------跟随路径生成物体

21.扫描网格_哔哩哔哩_bilibili

探索微服务治理:从发展到实践构建高效稳定的系统|负载均衡技术解析

二、微服务治理的相关技术 微服务治理涉及多个方面&#xff0c;包括服务注册与发现、负载均衡、容错处理、服务配置管理等&#xff0c;这些技术共同确保微服务架构的稳定运行。 2、负载均衡 负载均衡作为服务治理中的核心技术之一&#xff0c;对于提高系统的可用性、性能和扩…

迁移windows操作系统

最近有个朋友跟我说他电脑台卡了&#xff0c;我帮他大概看了下&#xff0c;归集原因磁盘还是机械硬盘&#xff0c;需要将他的电脑的磁盘的机械硬盘换一下&#xff0c;内存也比较小&#xff0c;4GB的&#xff0c;换一下&#xff0c;换成8GB的&#xff0c;本文只涉及到更换系统盘…

【CSS3线性渐变·元素转换·HTML】

线性渐变 线性渐变是向下、向上、向左、向右、对角方向的颜色渐变。 background-image: linear-gradient(); .gradient2 {margin-left: 10px;width: 100px;height: 100px;background-image: linear-gradient(to right, #ff9d72, #c6c9ff);}/*从左上角到右下角的渐变*/.gradien…

three.js CSS3DRenderer、CSS3DSprite渲染HTML标签

有空的老铁关注一下我的抖音&#xff1a; 效果: <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red;position: relative;"></div><…

杂题——试题 算法训练 区间最大和

分析&#xff1a; 如果使用两个for循环遍历所有情况&#xff0c;运行会超时解决运行超时的关键点在于&#xff1a;及时停止累加&#xff0c;丢弃当前的子序列 比如【1&#xff0c;-2&#xff0c;3&#xff0c;10】从第一个数字开始的子序列的和小于从第三个数字开始的子序列的和…

uniapp+微信小程序+nodejs问题记录

一、前言 通过uniapp进行微信小程序调试。服务端使用NodeJs。 二、报错统计 1、本地调试时微信小程序报错&#xff1a;request:Cannot send network request to localhost 解决方法&#xff1a; 【微信小程序开发平台】-【本地设置】-勾选“不校验合法域名、web-view、TLS版本…

Vue Router

Vue Router 一、Vue Router 回顾 1、路由简介 路由是一个比较广义和抽象的概念&#xff0c;路由的本质就是对应关系。 在开发中&#xff0c;路由分为&#xff1a; ​ 后端路由​ 前端路由 后端路由 概念&#xff1a;根据不同的用户 URL 请求&#xff0c;返回不同的内容本…

在bash或脚本中,如何并行执行命令或任务(命令行、parallel、make)

最近要批量解压归档文件和压缩包&#xff0c;所以就想能不能并行执行这些工作。因为tar自身不支持并行解压&#xff0c;但是像make却可以支持生成一些文件&#xff0c;所以我才有了这种想法。 方法有两种&#xff0c;第一种不用安装任何软件或工具&#xff0c;直接bash或其他 …

2024年大数据方向的发展趋势

最近事情较多&#xff0c;因为临近年底&#xff0c;在做总结和后续规划&#xff0c;在这一年中&#xff0c;数据开发方向仍然在快速发展&#xff0c;新概念和新技术层出不穷。 并且2023年是各大公司新技术大规模落地的一年&#xff0c;相比2022年及以前空中楼阁似的讨论和不接地…

qt学习:停车场管理系统+摄像头+http识别车牌+sqlite3数据库

目录 参考前面发的几篇文章http识别车牌&#xff0c;sqlite3数据库、摄像头的文章 步骤 部分代码 新建一个项目&#xff0c;加入前面用到的http和image两个文件&#xff0c;和加入用到的模块和头函数和成员&#xff0c;加入前面用到的全局变量 配置ui界面 在构造函数中初…

Tomcat 部署项目时 war 和 war exploded区别

在 Tomcat 调试部署的时候&#xff0c;我们通常会看到有下面 2 个选项。 是选择war还是war exploded 这里首先看一下他们两个的区别&#xff1a; war 模式&#xff1a;将WEB工程以包的形式上传到服务器 &#xff1b;war exploded 模式&#xff1a;将WEB工程以当前文件夹的位置…

Linux下Docker搭建部署Typecho博客【详细版】

Linux下Docker搭建部署Typecho博客【详细版】 一、环境准备1.1.准备阿里云服务器【新用户免费使用三个月】1.2.准备远程工具【FinalShell】1.3.系统信息1.4.安装所需软件包1.5.设置docker镜像源1.6.更新yum软件包索引1.7.确认停用selinux 二、安装Docker2.1.安装Docker-Ce2.2.查…

智能预测:数字化时代的服装企业如何实现准确的需求规划

在数字化时代&#xff0c;智能预测成为服装企业实现准确需求规划的关键。通过充分利用先进的技术手段&#xff0c;企业能够更精准地洞察市场动态、了解消费者行为&#xff0c;从而使生产计划更加敏捷、高效。以下是数字化时代服装企业实现准确需求规划的关键步骤和策略。 1.数…