C++类和对象-->默认成员函数

news2024/11/25 16:56:16

文章目录

  • 类的6个默认成员函数
  • 初始化和清理
    • 构造函数
      • 构造函数概念
      • 构造函数特征
    • 析构函数
      • 析构函数概念
      • 析构函数特征
  • 拷贝赋值
    • 拷贝构造函数
      • 拷贝构造函数概念
      • 拷贝构造函数特征
    • 赋值运算重载
      • 运算符重载
        • 运算符重载特征
      • 赋值运算符重载
        • 赋值运算符特征
  • 取地址重载
    • 取地址操作符重载
    • const取地址操作符重载
      • const成员函数

大纲
在这里插入图片描述

类的6个默认成员函数

如果一个类中什么成员都没有 称之为空类

class Empty
{
};

空类并不是什么都没有 编译器会自动生成6个默认成员函数
默认成员函数: 用户自己没有写 编译器会自动生成 若用户自己写了 则不会自动生成

初始化和清理

构造函数

构造函数概念

构造函数是一种特殊的成员函数 名字和类的名字一样 创建类类型时由编译器自动调用 用来完成对象资源的初始化工作 在整个生命周期内只调用一次
比如下面这个Date类

class Date
{
public: 
	Date()
	{
		_year = 0;
		_month = 0;
		_day = 0;
	}
	void Print()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Print();//打印结果为0-0-0
	return 0;
}

Date就是成员函数就是一个构造函数 创建一个Date对象实例化时 编译器会自动调用这个构造函数对成员变量进行初始化

构造函数特征

在这里插入图片描述

1.函数名与类名相同
2. 无返回值
无返回值不是void 是不用指定函数类型
3. 对象实例化时编译器自动调用对应的构造函数
4.构造函数可以重载

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

   void Print()
   {
   	cout << _year << '-' << _month << '-' << _day << endl;
   }

private:
   int _year;
   int _month;
   int _day;
};
int main()
{
   Date d1;//调用无参构造函数
   d1.Print();
   Date d2(2023, 10, 21);//调用有参构造函数
   d2.Print();
   return 0;
}

构造函数也支持缺省值 上面的代码可以改写成这样

class Date
{
public: 
	Date(int year = 0, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Print();
	Date d2(2023, 10, 21);
	d2.Print();
	return 0;
}

5.如果类中用户没有定义构造函数 则编译器会自动生成一个无参的默认构造函数 一但用户定义 编译器便不在生成

//编译器自动生成构造函数
class Date
{
public: 
	void Print()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;//调用编译器生成的构造函数初始化
	d1.Print();//打印结果为随机值
	return 0;
}

初始化结果为随机值??? 这里的构造函数貌似没什么用
编译器自动生成构造函数的规则
在这里插入图片描述

对内置类型(int/char/指针类型等)不做处理
对自定义类型(class/struct/union等)会自动调用默认构造函数

c++11中针对内置类型成员不初始化的缺陷 打了新补丁 即内置成员变量在类中声明可以给默认值
仅仅只是声明 并没有定义 没有开空间

class Date
{
public: 
	void Print()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}
private:
	int _year = 0;
	int _month =0;
	int _day =0;
};
int main()
{
	Date d1;//调用编译器生成的构造函数初始化
	d1.Print();//打印结果为0-0-0
	return 0;
}

6.无参构造函数和全缺省构造函数和编译器默认生成的构造函数都称为默认构造函数
默认构造函数有且只能有一个
在这里插入图片描述

错误示例 : 无参和全缺省同时出现

class Date
{
public: 
	Date()
	{
		_year = 1;
		_month = 1;
		_day = 1;
	}
	Date(int year = 0, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Print();
	return 0;
}

结合构造函数的特征 :一般情况下都需要自己写构造函数 成员时自定义类型 或者声明给了缺省值 可以考虑让编译器生成默认构造函数

析构函数

析构函数概念

与构造函数的功能相反 析构函数不是完成对象本身的销毁工作 局部对象销毁工作是由编译器完成的 而对象在销毁时会自动调用析构函数 完成对象中的资源清理工作

析构函数特征

在这里插入图片描述

1、析构函数的函数名 == ~类名

class Date
{
public:
	Date()//构造函数
	{

	}
	~Date()//析构函数
	{

	}
};

2、析构函数和构造函数一样无返回值 还有一点是无参函数
3、一个类只能有一个析构函数 如果未定义 编译器会自动生成默认的析构函数
默认析构函数规则和构造函数一样
4、析构函数不能重载结合2 3特性
5、对象生命周期结束时 c++编译器自动调用析构函数

class Date
{
public: 
	~Date()
	{
		cout << "111" << endl;
	}
private:
	int _year;
	int _month;
	int _day;

};
int main()
{
	Date d1;//会打印111 编译器自动调用析构函数
	return 0;
}

结合析构函数的特征 一般如果类中没有资源申请时 析构函数可以不写 直接使用编译器默认生成的即可;
如果有资源申请时 一定要写 否则会造成内存泄漏

拷贝赋值

拷贝构造函数

拷贝构造函数概念

只有单个形参 该形参是对本类类型对象的引用一般用const修饰,在用已存在的类类型对象创建新对象时由编译器自动调用

class Date
{
public:
	Date(int year = 1, int month = 1 , int day = 1)//构造函数
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)//拷贝构造函数  d是d1的别名 ,this指向d2
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void Print()
	{
		cout << _year<< "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023,10,27);
	d1.Print();
	Date d2(d1);//用d1去初始化d2
	d2.Print();
	return 0;
}

拷贝构造函数特征

在这里插入图片描述

1、是构造函数的一个重载形式
拷贝构造函数名也和类名相同 参数一般和构造函数不同
2、参数只能有一个且必须是类类型对象的引用

Date(const Date d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}

上面的Date类拷贝构造函数写成这样的话会引发无穷递归 聪明的编译器会直接报错

3、若未定义 则编译器会默认生成拷贝构造函数

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;

	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Print();
	Date d2(d1);//用d1去初始化d2
	d2.Print();
	return 0;
}

默认生成拷贝构造函数的规则:
在这里插入图片描述

下面举个例子

class Time
{
public:
	Time(int _hour = 1, int _minute = 1, int _second = 1)//构造函数
	{}
	Time(const Time& t)//拷贝构造函数
	{
		cout << "Time(const Time& t)" << endl;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	//内置类型
	int _year;
	int _month;
	int _day;
	//自定义类型
	Time _t;
};
int main()
{
	Date d1;
	Date d2(d1);//用d1拷贝构造d2 此处会调用Date类的拷贝构造函数
	            //但是Date的拷贝构造函数是编译器默认生成的 自定义变量_t就会去调用Time类的拷贝构造
	            //所以这里会打印 Time(const Time& t)
	return 0;
}

4、编译器自动生成的不能完成深拷贝
错误示范

class Stack
{
public:
	Stack(int capacity = 10)//构造函数
	{
		_arr = (int*)malloc(sizeof(int) * capacity);
		if (_arr == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		_size = 0;
		_capacity = capacity;
	}
	~Stack()//析构函数
	{
		free(_arr);
		_arr = nullptr;
		_size = _capacity = 0;
	}
	void Push(int x)
	{
		_arr[_size] = x;
		_size++;

	}
private:
	int* _arr;
	int _size;
	int _capacity;
};
int main()
{
	Stack s1;
	s1.Push(1);
	s1.Push(2);

	Stack s2(s1);//
	return 0;
}

上面栈这个例子s1对象调用构造函数初始化 然后存放了2个数据1和2
s2对象使用s1的拷贝构造,Stack类中没有自己实现这个函数 所以编译器会默认生成一个拷贝构造函数 默认的拷贝构造函数是按照值拷贝的 将s1中内容原封不动拷贝到s2中 因此s2和s1指向了同一块内存空间
在这里插入图片描述
当程序退出时 s1和s2 要销毁 s2销毁时回去调用析构函数 以及释放了0x0000017f49e6d510这块空间 ,s1再销毁 也会去销毁这块空间 ,一块空间同时多次释放 会引起程序奔溃
实际的栈中 s2和s1应该是不同空间的两个对象这个代码显然是不能完成的
结合拷贝构造函数的特征 如果类中没有设计到资源申请时,拷贝构造函数写不写都可以,编译器默认生成可以完成了;如果有涉及到资源申请时 则拷贝构造函数时一定要自己实现的,否则就是浅拷贝
上面例子的拷贝构造函数的正确实现方式

Stack(const Stack& stt)//	拷贝构造函数
	{
		// 深拷贝
		_arr = (int*)malloc(sizeof(int) * stt._capacity);
		if (_arr == nullptr)
		{
			perror("malloc fail");
			exit(-1);
		}
		memcpy(_arr, stt._arr, sizeof(int) * stt._size);
		_size = stt._size;
		_capacity = stt._capacity;
	}

赋值运算重载

运算符重载

内置类型运算符一般有算术运算符 关系运算符 比较运算符 赋值运算符等等
如何实现自定义类型的运算 比如判断两个日期是否相等
可以用一个函数进行判断 例如

bool IsSame(Date& x,Date& y)
	{
		if (x._year == y._year && x._month == y._month && x._day == y._day)
			return true;
		else
			return false;
	}

这样写最大的缺点是可读性太差 C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数
可以重定义或重载大部分 C++ 内置的运算符。这样,就能使用自定义类型的运算符

运算符重载特征

在这里插入图片描述

1、运算符重载函数格式
函数原型:返回值类型 operator操作符(参数列表)
2、重载运算符必须有一个类类型参数

bool operator==(int, int );//错误示范
bool operator==(int, Date );//正确

3、对内置类型运算符含义不能改变
4、作为类成员函数重载时 函数有一个默认的形参this
错误示范

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)//构造函数
	{
		_year = year;
		_month = month;
		_day = day;
	}
	bool operator==(const Date& x, const Date& y)//运算符重载函数
	{
		return x._year == d._year
			&& x._month == d._month
			&& x._day == d._day;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	Date d2(2023,10,28);
	return 0;
}

作为类成员函数时 这样的写法是错误的 因为还有一个this ==的操作数只有两个 参数有三个了 编译器会报错
正确实现运算重载函数

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

可以看成下面这种写法

bool operator==(const Date& y)
{
	return this->_year == y._year
		&& this->_month == y._month
		&& this->_day == y._day;
}

5、编译器不会默认生成 需要自己实现
运算符包含关系运算符 算数运算符 逻辑运算符 赋值运算符 等等 只有赋值运算符函数编译器才会默认生成
6、.* :: sizoef ?: . 不支持重载

赋值运算符重载

赋值元素符和其他运算符不同 他会更新变量的值
内置类型的赋值运算符一般有 = += -= /= *= …等等

赋值运算符特征

在这里插入图片描述

1、赋值运算符重载的格式

  • 参数类型 :const 类名& 传引用可以提高传参效率
  • 返回值类型: 类名& 返回引用可以提高返回的效率 有返回值目的是为了支持连续赋值
  • 返回*this 要符合连续赋值的含义
  • 检查是否自己给自己赋值
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)//构造函数
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date& operator=(const Date& d)//赋值运算符重载函数
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
		return *this;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(1,1,1);
	Date d2(2,2,2);
	d1 = d2;//将d2赋值给d1
	d1.Print();//打印2-2-2
	d2.Print();//打印2-2-2
}

2、赋值运算符只能重载成类的成员函数 不能重载成全局函数
错误示范

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;
	}
private:
	int _year;
	int _month;
	int _day;
};
Date& operator=(const Date& d)//赋值运算符重载函数
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
	return *this;
}

赋值运算符如果不写 编译器会默认生成一个 我们再在类外面自己实现一个全局的 就会和默认的发生冲突 所以赋值运算符重载只能是类的成员函数
3、用户未定义 编译器默认生成一个
编译器默认生成的对内置类型完成值拷贝 对自定义类型会去调用他自己的赋值运算符重载函数

class Time
{
public:
	Time(int hour = 1,int minute = 1,int second = 1)
	{
		_hour = hour;
		_minute = minute;
		_second = second;
	}
	Time& operator=(const Time& t)
	{
		_hour = t._hour;
		_minute = t._minute;
		_second = t._second;
		cout << "Time& operator=(const Time& t)" << endl;
		return *this;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	int _year = 1;
	int _month =1 ;
	int _day =1;
	Time _t;//自定义类型t
};
int main()
{
	Date d1;
	Date d2;
	d1 = d2;
	return 0;
}

d2赋值给d1 Date成员中内置类型会去调用默认生成的赋值运算符重载函数 自定义类型t会去调用自己的赋值运算符重载函数 所以程序会打印出Time& operator=(const Time& t)
默认生成的赋值运算符函数可以完成字节序的值拷贝 有些场景还需要自己实现的 和拷贝构造函数一样

取地址重载

取地址操作符重载

class Date
{
public:
	Date* operator&()//取地址操作符重载函数
	{
		cout << "Date* operator&()" << endl;
		return this;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	cout << &d1 << endl;
	return 0;
}

上面例子会打印Date* operator&() 以及d1的地址
如果上面的取地址操作符重载函数写成这样

Date* operator&()
{
	return NULL;
}

返回的就是0地址 这样写一般也没有应用场景 取地址操作符重载一般用编译器自己默认实现的即可

const取地址操作符重载

在介绍const取地址操作符重载函数之前先介绍一下const成员函数

const成员函数

我们将用const修饰的成员函数称之为const成员函数
const修饰类的成员函数实际上是修饰该成员函数隐含的this指针,表明在该成员函数中不对类的任何成员进行修改
下面这个例子

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "Print()" << endl;
	}
	void Print() const//const成员函数
	{
		cout << "Print() const" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023,11,02);
	d1.Print();//打印Print()

	const Date d2(2023,11,02);
	d2.Print();//打印Print() const
	
	return 0;
}

非const对象d1 会去调用非const成员函数
const对象d2调用const成员函数
改写成下面这种写法

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print() const//const成员函数
	{
		cout << "Print() const" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023,11,02);
	d1.Print();//打印Print()const

	const Date d2(2023,11,02);
	d2.Print();//打印Print() const
	
	return 0;
}

非const对象d1 和const对象d2 都会区调用const成员函数
改写下面这种写法

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "Print()" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023,11,02);
	d1.Print();//打印Print()const

	const Date d2(2023,11,02);
	d2.Print();//error
	
	return 0;
}

非const对象d1 会去调用非const成员函数
但是用const对象d2调用非const成员函数 会报错
原因是因为成员函数隐含的this指针的类型是Date* const this 而d2是const Date类型 类型不匹配
总和上面的例子
const对象只能调用const成员函数
非cosnt对象既能调用cong成员函数也可以调用非const成员函数
如果某些成员函数需要修改成员变量 那么则不能使用const修饰
能用const修饰的成员函数 一般都应该定义成cosnt

下面再来看const取地址操作符重载

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	Date* operator&() 
	{
		cout << "Date* operator&() " << endl;
		return this;
	}
	
	const Date* operator&() const 
	{
		cout << "const Date* operator&() const  " << endl;
		return this;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	cout << &d1 << endl;//打印Date* operator&() 然后在打印d1的地址

	const Date d2;
	cout << &d2 << endl;//打印const Date* operator&() const 然后打印d2的地址
	return 0;
}

编译器会去调用和自己匹配的成员函数
一般这两个成员函数直接使用编译器默认生成的即可 不用自己实现

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

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

相关文章

C#中使用LINQtoSQL管理SQL数据库之添加、修改和删除

目录 一、添加数据 二、修改数据 三、删除数据 四、添加、修改和删除的源码 五、生成效果 1.VS和SSMS原始记录 2.删除ID2和5的记录 3.添加记录ID2、5和8 4.修改ID3和ID4的记录 用LINQtoSQL管理SQL Server数据库时&#xff0c;主要有添加、修改和删除3种操作。 项目中创…

Unity AssetBundle批量打包、加载(场景、Prefab)完整流程

目录 1、文章介绍 2、具体思路和写法 &#xff08;1&#xff09;AB包的打包 &#xff08;2&#xff09;AB包的加载 &#xff08;3&#xff09;AB包卸载 3、结语 1、文章介绍 本篇博客主要起记录和学习作用&#xff0c;简单的介绍一下AB包批量的打包和加载AB包的方式&…

项目实战:编辑页面加载库存信息

1、前端编辑页面加载水果库存信息逻辑edit.js let queryString window.location.search.substring(1) if(queryString){var fid queryString.split("")[1]window.onloadfunction(){loadFruit(fid)}loadFruit function(fid){axios({method:get,url:edit,params:{fi…

【IIS搭建网站】在本地电脑上搭建web服务器并实现外网访问

文章目录 1.前言2.Windows网页设置2.1 Windows IIS功能设置2.2 IIS网页访问测试 3. Cpolar内网穿透3.1 下载安装Cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5.结语 1.前言 在网上各种教程和介绍中&#xff0c;搭建网页都会借助各种软件的帮助&#xf…

【APP】go-musicfox - 一款网易云音乐命令行客户端, 文件很小Mac版本只有16.5M

go-musicfox 是用 Go 写的又一款网易云音乐命令行客户端&#xff0c;支持各种音质级别、UnblockNeteaseMusic、Last.fm、MPRIS 和 macOS 交互响应&#xff08;睡眠暂停、蓝牙耳机连接断开响应和菜单栏控制等&#xff09;等功能特性。 预览 启动 启动界面 主界面 主界面 通…

【docker】安装 showdoc

1. 下载镜像 2.新建存放showdoc数据的目录 3.启动showdoc容器 4.打开网页 1. 下载镜像 # 原版官方镜像安装命令(中国大陆用户不建议直接使用原版镜像&#xff0c;可以用后面的加速镜像) docker pull star7th/showdoc # 中国大陆镜像安装命令&#xff08;安装后记得执行docke…

数组反转(LeetCode)

凑数 ... 描述 : 给你一个 32 位的有符号整数 x &#xff0c;返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] &#xff0c;就返回 0。 假设环境不允许存储 64 位整数&#xff08;有符号或无符号&#xff09;。 题目…

Dubbo中的负载均衡算法之一致性哈希算法

Dubbo中的负载均衡算法之一致性哈希算法 哈希算法 假设这样一个场景&#xff0c;我们申请一台服务器来缓存100万的数据&#xff0c;这个时候是单机环境&#xff0c;所有的请求都命中到这台服务器。后来业务量上涨&#xff0c;我们的数据也从100万上升到了300万&#xff0c;原…

VS使用小技巧——如何让别人看不到你写的代码,却能够运行你的代码

VS使用小技巧 前言方法使用静态库的示例如何创建静态库如何导入静态库Xcode里导入静态库VS2022导入静态库 前言 在实际生活中&#xff0c;作为程序员偶尔会因为资金不够用了选择去兼职写代码&#xff0c;当我们写完一个代码&#xff0c;将他发给某个公司的时候&#xff0c;我们…

C++——定义一个 Box(盒子)类,在该类定义中包括数据成员和成员函数

完整代码&#xff1a; /*定义一个 Box(盒子)类&#xff0c;在该类定义中包括数据成员和成员函数。 数据成员&#xff1a;length &#xff08;长&#xff09;、width&#xff08;宽&#xff09;和 height&#xff08;高&#xff09;&#xff1b; 成员函数&#xff1a;构造函数 …

阿里云双十一大促:云服务器1年99元,新老同享,续费同价!

2023年双十一购物狂欢节来临&#xff0c;阿里云推出了金秋云创季活动&#xff0c;活动力度很大&#xff0c;不再是老用户与狗不得入内&#xff0c;2核2G3M云服务器1年99元&#xff0c;新老同享&#xff0c;续费同价&#xff01; 活动地址&#xff1a;传送门>>> 活动详…

【C++】C++11【下】lambda表达式|thread线程库

目录 1、lambda表达式 1.1 lambda表达式的引入 1.2 lambda表达式的语法 1.3 lambda表达式的原理 2、线程库 2.1thread类的介绍 2.2 线程函数参数 2.3 原子性操作库(atomic) 2.4 使用场景 应用场景1&#xff1a; 应用场景2: 应用场景3&#xff1a; 应用场景4&#xf…

SAFe大规模敏捷框架

Leangoo领歌是一款永久免费的专业的敏捷开发管理工具&#xff0c;提供端到端敏捷研发管理解决方案&#xff0c;涵盖敏捷需求管理、任务协同、进展跟踪、统计度量等。 
 Leangoo领歌上手快、实施成本低&#xff0c;可帮助企业快速落地敏捷&#xff0c;提质增效、缩短周期、加速…

与AI对话的艺术:如何优化Prompt以获得更好的响应反馈

前言 在当今数字化时代&#xff0c;人工智能系统已经成为我们生活的一部分。我们可以在智能助手、聊天机器人、搜索引擎等各种场合与AI进行对话。然而&#xff0c;要获得有益的回应&#xff0c;我们需要学会与AI进行有效的沟通&#xff0c;这就涉及到如何编写好的Prompt。 与…

【Linux学习笔记】进程概念(下)

进程地址空间1. 虚拟地址2. 什么是进程地址空间3. 进程地址空间的映射。4. 地址空间存在的意义5. 写时拷贝 进程地址空间 1. 虚拟地址 来看这样一段代码。 #include <stdio.h> #include <unistd.h>int global_value 100;int main() {pid_t id fork();if(id &l…

3206. 拼图

给出一个 nm 的方格图&#xff0c;现在要用如下 L 型的积木拼到这个图中&#xff0c;使得方格图正好被拼满&#xff0c;请问总共有多少种拼法。 其中&#xff0c;方格图的每一个方格正好能放积木中的一块。 积木可以任意旋转。 输入格式 输入的第一行包含两个整数 n,m&#xff…

scrapy+selenium框架模拟登录

目录 一、cookie和session实现登录原理 二、模拟登录方法-Requests模块Cookie实现登录 三、cookiesession实现登录并获取数据 四、selenium使用基本代码 五、scrapyselenium实现登录 一、cookie和session实现登录原理 cookie:1.网站持久保存在浏览器中的数据2.可以是长期…

3D视觉引导工业机器人上下料,助力汽车制造业实现智能化生产

在工业制造领域&#xff0c;机器人技术一直是推动生产效率和质量提升的重要力量。近年来&#xff0c;随着3D视觉技术的快速发展&#xff0c;工业机器人在处理复杂任务方面迈出了重要的一步。特别是在汽车制造行业&#xff0c;3D视觉引导工业机器人的应用已经取得了令人瞩目的成…

dockefile

文章目录 应用的部署MySql的部署Tomcat的部署 dockerfileDocker原理镜像的制作容器转镜像Dockerfile 服务编排Docker Compose Docker 私有仓库 应用的部署 搜索app的镜像拉去app的镜像创建容器操作容器中的app MySql的部署 容器内的网络服务和外部机器无法直接通信外部机器和…

软件测试 —— 移动端测试

1. 移动端 指移动设备&#xff08;如智能手机、平板电脑、智能手表等&#xff09;上的操作系统和应用程序。移动设备具有便携性和多功能性&#xff0c;可以随时随地连接互联网&#xff0c;提供丰富的应用和服务。 2. 移动端应用分类 (1) 原生应用&#xff08;Native App&…