【C++】类和对象(三)再探构造函数|static成员函数|友元函数|内部类|匿名对象|对象拷贝时的编译优化

news2024/9/24 5:30:16


欢迎来到Harper·Lee的学习笔记!

一、再探构造函数

  1. 初始化列表:构造函数初始化的第二种方式(第一种是使用函数体内赋值)。
  2. 使用方式:以一个冒号:开始,用逗号,分隔数据成员列表,每个成员变量后面跟一个放在括号里面的初始值或者表达式,建议一个成员变量写成一行。
  3. 注意事项:每个成员变量只能出现一次(即只能初始化一次),所以可以理解为:初始化列表是每个成员变量定义初始化的地方。
class Date
{
public:
	Date(int year, int month, int day)
    //初始化列表:
		:_year(year)
		, _month(month)
		, _day(day)//建议一个值写成一行
		//, _year(1);//error,只能初始化一次
	{ }
private:
	//声明:
	int _year;
	int _month;
	int _day;
};
  1. 只能在初始化列表进行初始化的成员变量:(必须在定义的地方即初始化列表进行初始化
  • const修饰的成员变量,原因:只能在它定义的地方(即:初始化列表)进行初始化,否则后续就不能修改了。
#include <iostream>
using namespace std;

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
		,_n(1)//right
	{
		//_n = 1;//error C2789: “Date::_n”: 必须初始化常量限定类型的对象
	}
private:
	//声明:
	int _year;
	int _month;
	int _day;

	//1.const修饰的成员变量
	const int _n;
};
  • 引用成员变量,原因:引用必须要进行初始化,必须要在定义的地方进行初始化,必须要知道该引用是谁的别名。
#include <iostream>
using namespace std;

class Date
{
public:
	Date(int& m, int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
		//,_ref(m)//error C2530 : “Date::_ref” : 必须初始化引⽤
	{}
private:
	//声明:
	int _year;
	int _month;
	int _day;

	//2.引用成员变量
	int& _ref;
};
  • 没有默认构造的类类型变量,原因:如果有默认构造函数,那么初始化列表中可写可不写;如果没有默认构造函数,为了定义初始化,只能自己在初始化列表传入值。
#include <iostream>
using namespace std;

class Time
{
public:

	//全缺省构造函数就是默认构造
	//Time(int hour = 0)
	//	:_hour(hour)
	//{
	//	cout << "Time()" << endl;
	//}

	Time(int hour)//error C2512: “Time”: 没有合适的默认构造函数可用
		:_hour(hour)
	{
		cout << "Time()" << endl;
	}
private:
	int _hour;
};

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
		,_t(1)//没有默认构造的情况下,必须使用初始化列表,
        //否则 error C2512: “Time”: 没有合适的默认构造函数可用
	{}
private:
	//声明:
	int _year;
	int _month;
	int _day;

	//3.没有默认构造的类类型对象
	Time _t;
};
int main()
{	
	Date d1(2024, 7, 14);
	return 0;
}

运行结果:

Time();

  1. 初始化列表和函数体可以进行混用。
class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
		,_ptr((int*)malloc(12))
	{
		if (_ptr == nullptr)
		{
			perror("malloc fail");
		}
		else
		{
			memset(_ptr, 0, 12);
		}
	}
private:
	//声明:
	int _year;
	int _month;
	int _day;

	//函数体和初始化列表可以进行混用
	int* _ptr;
}; 

  1. 有些变量可以不进行初始化。
#include <iostream>
using namespace std;

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		//, _day(day)//没有进行初始化
	{}
	void Print() const
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
private:
	//声明:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2024, 7, 14);
	d1.Print();

	return 0;
}

运行结果:

2024年7月-858993460日

  1. C++11的另类写法:声明成员变量时为它们赋缺省值/默认值,就可以用于初始化列表的初始化。(相当于初始化列表没写的成员,声明里面的缺省值会走到初始化列表里面去)
#include <iostream>
using namespace std;

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		//, _day(day)//没有显示在初始化列表
	{}
	void Print() const
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
private:
	//仍然是声明:每个成员变量赋有一个缺省值--是初始化时的备选之策
	int _year = 1;
	int _month = 1;
	int _day = 27;
};

int main()
{
	Date d1(2024, 7, 14);
	d1.Print();

	return 0;
}

运行结果:

2024年7月27日

  • 我们不写构造函数时,编译器会自动生成一个默认构造函数,在原来内置类型是不会进行初始化的,但是C++11给了缺省值,无论是我们自己写的默认构造还是自动生成的构造都会使用该缺省值进行初始化。
#include <iostream>
using namespace std;

class Date
{
public:
	//Date(int year, int month, int day)
	//	:_year(year)
	//	, _month(month)
	//	//, _day(day)
	//{}
	void Print() const
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}
private:
	//声明:
	int _year = 1;
	int _month = 1;
	int _day = 27;
};

int main()
{
	Date d1;
	d1.Print();

	return 0;
}

运行结果:

1年1月27日

  • 如果你没有给缺省值,对于没有显示在初始化列表初始化的内置类型成员是否初始化取决于编译器,C++并没有规定。对于没有显示在初始化列表初始化的自定义类型成员会用这个成员类型的默认构造函数,如果没有默认构造会编译错误。

梳理总结:每个构造函数都有初始化列表。

Q:如果在函数形参的位置给了缺省值,那么声明位置还需要缺省值吗?

A:两者并无关联。

  1. 初始化顺序:初始化列表中按照成员变量在类中声明顺序进行初始化,与成员在初始化列表出现的先后顺序无关,建议声明顺序和初始化顺序保持一致。(声明顺序其实就是变量在内存中存放的顺序)(可以调试观察顺序、运行顺序)
  2. 例题练手:下面代码的运行结果:
#include<iostream>
using namespace std;
class A
{
public:
	A(int a)
		:_a1(a)
		, _a2(_a1)
	{}
	void Print() {
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a2 = 2;//先声明
	int _a1 = 2;//后声明
};
int main()
{
	A aa(1);//这里并没有开辟空间,函数创建的时候开辟了空间
    //A aa;
	aa.Print();
}

运行结果:

1 -858993460

构造函数传入缺省值,类创建的对象不传入缺省值,调试发现仍然是按照声明顺序进行初始化(没往列表走是为了方便观看)

二 、类型转换

隐式类型转换,不是任意类型都可以进行隐式类型转换的。

//Date.cpp  
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;

class A
{
public:
	A(int a = 0)//提供默认构造函数
	//explicit A(int a = 0);
	{
		_a1 = a;
	}
	A(const A& aa)
	{
		_a1 = aa._a1;
	}
	void Print()
	{
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a1;
	int _a2;
};

class  Stack
{
public:
	void Push(const A& aa)
	{
		//……
	}
private:
	A _arr[10];
	int _top;
};

int main()
{
	A aa1(1);// 调用构造函数
	aa1.Print();

	//隐式类型转换:int类型转换成A类型
	//2 构造出 A的临时对象,再用临时对象去 拷贝构造 aa2
	//但是:编译器遇到连续构造+拷贝构造--->相当于直接优化为直接构造(这是优化后的结果)
	A aa2 = 2;//不是任意类型都可以支持隐式类型转换
	aa2.Print();

	A& raa1 = aa2;//raa1引用aa2: ok
	//A& raa2 = 2;  //raa2引用2: error
	//原因:类型转换,中间会生成临时变量,具有常性。
	const A& raa2 = 2;//right

	int i = 1;
	double d = i;//隐式类型转换,中间会产生临时变量
	//i给临时变量,临时变量给d
	const double& ra = i;//这点在某个地方讲过!!!!!!!!!!!翻看笔记
	
	//此设计的意义:

	Stack st;//实现一个栈
	A aa3(3);
	st.Push(aa3);//这两个数据插入的效果一样

	st.Push(3);//单参数支持,但是多参数就默认不支持这样写了了。


	//C++11就可以支持
	A aa5 = { 1,1 };
	const A& raa6 = { 2,2 };
	st.Push(aa5);
	st.Push({ 2,2 });


	return 0;
}
//如果不想发生类型转换,就可以在构造函数时就加入explicit

三、static成员函数

  1. 概念:用static修饰的成员变量,称之为静态成员变量,静态成员变量一定要在类外面进行初始化。静态成员变量不能在声明处给缺省值,因为缺省值用于初始化列表。
  2. 静态成员变量为所有类对象所共享,不属于某个具体的对象,不存放对象中,存放在静态区中。
#include<iostream>
using namespace std;
class A
{
public:

private:
	// 类里面声明,不能给缺省值,因为它是会用于初始化列表的
	static int _scount;
};

// 类外面初始化
int A::_scount = 0;
//相当于是静态的全局,只是被类域限制,在类外访问时需要指定类域(公有时)

int main()
{
    cout << sizeof(A) << endl;//大小并没有包含静态成员
    
	return 0;
}

运行结果:

1

  1. 静态成员函数没有this指针
  2. 静态成员函数中可以访问其他的静态成员,但是不能访问非静态的,因为非静态的成员函数都有隐含的this指针,而静态成员函数没有。
  3. 非静态的成员函数可以访问任意的静态变量和静态成员函数。(访问非静态的只需要通过this指针;访问静态的只需要突破类域,可通过类名::静态成员或者对象.静态成员来访问静态成员变量、静态成员函数。)
#include<iostream>
using namespace std;
class A
{
public:
    A()//构造
	{
		++_scount;
	}
	A(const A& t)//拷贝构造
	{
		++_scount;
	}
	~A()//析构
	{
		--_scount;
	}
	static int GetACount()//静态成员函数,没有this指针,可以访问其他静态成员
	{
		return _scount;
	}
	void func()
	{
		cout << _scount << endl;//非静态成员函数访问静态成员变量
		cout << GetACount() << endl;//非静态成员函数访问静态成员函数
	}
private:
	// 类里面声明,不能给缺省值
	static int _scount;
};

// 类外面初始化
int A::_scount = 0;//虽然是全局却被类域限制,在类外时需要指定类域(公有时)
int main()
{
	cout << A::GetACount() << endl;//静态成员函数:可以指定类域调用

	A a1, a2;
	A a3(a1);

	cout << A::GetACount() << endl;
	cout << a1.GetACount() << endl;

	return 0;
}
  1. 牛客例题描述:求<font style="color:rgb(102, 102, 102);">1+2+3+...+n</font>,要求不能使用乘除法、for、while、if……else、switch、case等关键字及条件判断语句(A ? B : C)。(A类与B类合作关系)
//一个类调用一次构造,一个数组调用n此构造
class Sum
{
public:
	Sum()//构造函数
	{
		_ret += _i;
		++_i;//这里就实现了累加
	}
	static int GetRet()//提供静态成员函数,用于访问提取静态成员变量_i的结果。
	{
		return _ret;
	}

private:
	//在类里面声明
	static int _i;
	static int _ret;
};

//在类外面初始化
int Sum::_i = 1;
int Sum::_ret = 0;

class Solution//函数框架在这里
{
public:
	int Sum_Solution(int n) 
	{
		Sum a[n];//用数组定义n个对象,就可以调用n次构造,
		//数组用变量来定义:必须要求编译器支持C99变长数组

        //Sum* p = new Sum[n];//也可以这样进行(如果编译器不支持C99变长数组时)
        //总之:我们要调用n次Sum的构造函数,new了一个对象
        return Sum::GetRet();
	}
};

根据此题总结:静态成员函数特别好的用处就是进行封装。将常用的功能封装成静态成员函数,供所有类使用。

  1. 构造顺序:局部静态的生命周期是全局的
  2. 析构顺序:

四、友元

  • 友元分为友元类和友元函数。它提供了一种突破类访问限定符封装的方式。在函数声明或者类声明的前面加friend,并且把友元声明放在一个类里面。

4.1 友元函数

  • 外部友元函数可访问类的私有和保护成员,友元函数仅仅是一种声明,它不是类的成员函数。
  • 需要在类外面访问类里面的私有成员时才设置友元。
  • 友元函数可以定义在类定义的任何地方声明,不受类访问限定符限制。(示好)
  • 一个函数可以是多个类的友元函数。(一个人可以是多个人的共同朋友)
  • 注意:友元声明用任何的类型和变量都要向上找,向上没有时进行前置声明,告诉有该东西存在。
#include<iostream>
using namespace std;
// 前置声明,否则A的友元函数声明编译器不认识B
class B;
class A
{
	// 友元声明
	friend void func(const A& aa, const B& bb);
private:
	int _a1 = 1;
	int _a2 = 2;
};
class B
{
	// 友元声明
	friend void func(const A& aa, const B& bb);
private:
	int _b1 = 3;
	int _b2 = 4;
};
void func(const A& aa, const B& bb)
{
	cout << aa._a1 << endl;
	cout << bb._b1 << endl;
}
int main()
{
	A aa;
	B bb;
	func(aa, bb);
	return 0;
}

4.2 友元类

  • 友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中私有和保护成员。
  • 友元类的关系是单向的,不具有交换性。比如A类是B类的友元,但是B类是A类的友元。
  • 友元类关系不能传递,A类是B类的友元,B类是C类的友元,但是A类不是C类的友元,只能说B是A和C的共同好友。(就像APP推荐的可能认识的人一样)
  • 友元会增加耦合度,破坏封装。类和类之间本就独立,友元破坏了这种独立。
//你要想访问我,你就必须成为我的friend
#include<iostream>
using namespace std;
class A
{
	// 友元声明
	friend class B;
private:
	int _a1 = 1;
	int _a2 = 2;
};
class B
{
public:
	void func1(const A& aa)
	{
		cout << aa._a1 << endl;
		cout << _b1 << endl;
	}
	void func2(const A& aa)
	{
		cout << aa._a2 << endl;
		cout << _b2 << endl;
	}
private:
	int _b1 = 3;
	int _b2 = 4;
};
int main()
{
	A aa;
	B bb;
	bb.func1(aa);
	bb.func1(aa);
	return 0;
}

五、内部类(本质是封装)

  1. 概念:一个类定义在另一个类的内部,这种类就叫做内部类。
  2. 注意:
  • 内部类是一个独立的类,跟定义在全局相比,它只是受外部类的类域和访问限定符的限制,所以外部类定义的对象中不包含内部类。
  • 内部类默认是外部类对的友元。
  1. B是A的友元,B可以访问A的私有。
  2. 内部类本质上也是一种封装,A与B紧密关联,A类实现出来主要是给B类用,就考虑将A类设计成B类的内部类。如果将其放在private/protected位置,那么A就是B的专属内部类,其他地方用不了。(A类与B类从属)

对上面的牛客题改造(换成内部类):

class Solution  
{
private:
	static int _i;
	static int _ret;
	class Sum
	{
	public:
		Sum()//构造函数
		{
			_ret += _i;
			++_i;//这里就实现了累加
		}
	};
public:
	int Sum_Solution(int n)
	{
		Sum a[n];

		//Sum* p = new Sum[n];
		//delete [] p;

		return _ret;
	}
};
int Solution::_i = 1;
int Solution::_ret = 0;

六、匿名对象

  1. 用类型(实参)定义出来的对象叫做匿名对象,相比之前我们定义的类型 对象名(实参)定义出来的叫有名对象。
  2. 匿名对象生命周期只在当前一行,一般临时定义一个对象当前用一下即可,就可以定义匿名对象。
#include <iostream>
using namespace std;
class A
{
public:
	A(int a = 0)//默认构造
		:_a(a)
	{
		cout << "A(int a)" << endl;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a;
};
class Solution 
{
public:
	int Sum_Solution(int n) 
	{
		//...
		return n;
	}
};

int main()
{
	A aa1;//不传参数时这样定义,有名对象
	//A aa1();//error,无法区分是函数声明还是对象定义
	
	A();//不传参的匿名对象
	A(1);//传参的匿名对象

	//有名对象:
	Solution st;
	cout << st.Sum_Solution(10) << endl;

	//匿名对象--生命周期只在自己那一行代码中
	Solution().Sum_Solution(10);
	cout << Solution().Sum_Solution(10) << endl;

	return 0;
}

七、对象拷贝时的编译优化

  • 现代编译器会为了尽可能提高程序的效率,在不影响正确性的情况下会尽可能减少一下传参和传返回值的过程中可以省略的拷贝。
  • 如何优化C++标准并没有严格规定,各个编译器会根据情况自行处理。当前主流的相对新一点的编译器对于连续一个表达式步骤中的连续拷贝会进行合并优化,有些更新更“激进”的编译器还会进行跨行跨表达式的合并优化。
#include<iostream>
using namespace std;
class A
{
public:
	A(int a = 0)
		:_a1(a)
	{
		cout << "A(int a)" << endl;
	}
	A(const A& aa)
		:_a1(aa._a1)
	{
		cout << "A(const A& aa)" << endl;
	}
	A& operator=(const A& aa)
	{
		cout << "A& operator=(const A& aa)" << endl;
		if (this != &aa)
		{

				_a1 = aa._a1;
		}
		return *this;
	}
	~A()
	{
		cout << "~A()" << endl;
	}
private:
	int _a1 = 1;
};
void f1(A aa)
{}
A f2()
{
	A aa;
	return aa;
}
int main()
{
	// 传值传参
	A aa1;
	f1(aa1);
	cout << endl;
	// 隐式类型,连续构造+拷贝构造->优化为直接构造
	f1(1);
	// 一个表达式中,连续构造+拷贝构造->优化为一个构造
	f1(A(2));
	cout << endl;
	cout << "***********************************************" << endl;
	// 传值返回
	// 返回时一个表达式中,连续拷贝构造+拷贝构造->优化一个拷贝构造 (vs2019)
	// 一些编译器会优化得更厉害,进行跨行合并优化,直接变为构造。(vs2022)
	f2();
	cout << endl;
	// 返回时一个表达式中,连续拷贝构造+拷贝构造->优化一个拷贝构造 (vs2019)
	// 一些编译器会优化得更厉害,进行跨行合并优化,直接变为构造。(vs2022)
		A aa2 = f2();
	cout << endl;
	// 一个表达式中,连续拷贝构造+赋值重载->无法优化
	aa1 = f2();
	cout << endl;
	return 0;
}

喜欢的uu记得三连支持一下哦!
在这里插入图片描述

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

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

相关文章

Linux 命令行/bash脚本 批量创建文件

目录 一. 命令行1.1 需求1.2 代码 二. bash脚本2.1 需求2.2 前置知识2.3 无进度条版本2.3.1 知识点2.3.2 代码2.3.3 效果 2.4 有进度条版本2.4.1 代码2.4.2 效果 一. 命令行 1.1 需求 在当目录下生成指定年份的文件&#xff0c;要求从生成1月到12月&#xff0c;每个月份的文件…

如何使用 update-alternatives 切换软件版本 ?

Debian 中的 update-alternatives 命令是系统上多版本软件管理的利器。它允许您轻松地在同一程序的不同版本之间切换。假设您在单个系统上安装了多个 Java 版本或 Python 版本&#xff0c;在 update-alternatives 的帮助下&#xff0c;您可以将程序的任何版本设置为系统的默认版…

SAP MM模块与FI模块集成之科目配置

1. 定义评估范围 OMWD 评估范围设置在工厂层&#xff0c;那么系统自动建立和工厂具有相同ID的评估范围 IMG&#xff1a;物料管理>评估和科目设置>科目确定>无向导的科目确定>将评估范围群集分组 提示&#xff1a;评估层级——评估分组代码——评估范围。 2. OBYC…

【Unity案例】搭建射击系统与UI

上期将基础的移动系统搭建完毕后就可以开始搭建更加复杂的系统部分了 前排提示&#xff0c;由于一开始仅思考如何完成操作相关功能&#xff0c;以至于到后面重构稍微有些困难&#xff0c;继续写下去恐成屎山&#xff0c;故在搭完射击和武器UI后不再继续泛化到敌人和敌人状态机…

SF-HCI-SAP问题收集18:员工上级经理无效

导读 INTRODUCTION CPI集成&#xff1a;这几天一直在处理SuccessFactors与SAP集成的问题&#xff0c;因为没有给deubg权限&#xff0c;排查比较困难&#xff0c;这次讲解的案例就是一个比较难发现的案例&#xff0c;在同步员工主数据的时候提示&#xff0c;经历在某个区间无效…

前端原生Js批量修改页面元素属性的2个方法

前言 嘿&#xff0c;朋友们&#xff01;今天咱们来聊聊一个前端原生 JS 的小技巧。 今天在做一个 RPA 机器人时&#xff0c;碰到一个业务需求&#xff0c;网页上有两个日期控件元素&#xff0c;它们的输入框有 readonly 属性&#xff0c;只能通过选择的方式来输入日期&#x…

数据库和MySQL

ER图 实体&#xff08;矩形&#xff09;&#xff1a;通常是现实世界的业务对象&#xff0c;当然使用一些逻辑对象也可以。 属性&#xff08;椭圆&#xff09;&#xff1a;实体拥有的属性。 联系&#xff08;菱形&#xff09;&#xff1a;实体与实体之间的关系。 函数依赖 函数依…

idea 编译断点运行 tomcat 10.1.28 源码

idea 编译运行 tomcat 10.1.28 源码 1. 所需资源 tomcat 10.1.28 zulu JDK 22 maven idea (支持 JDK 22) 2. Idea 导入项目 10.1.28.tar.gz 解压到指定文件夹 如 ~\tomcat-source\tomcat-10.1.28 这里等待一段时间&#xff0c;生成 ~\tomcat-source\tomcat-10.1.28\.idea 文…

双向链表

双向链表是一种基本的数据结构&#xff0c;它与单向链表的主要区别在于节点的连接方式。下面我将分别描述双向链表的特点以及它与单向链表的区别。 双向链表的特点&#xff1a; 节点结构&#xff1a;在双向链表中&#xff0c;每个节点包含三个部分&#xff1a;数据域、指向前一…

WordPress自适应美图网站整站打包源码

直接服务器整站源码数据库打包了&#xff0c;恢复一下就可以直接投入使用。保证好用易用&#xff0c;无需独立服务器就可以使用。 强调一下&#xff0c;我这个和其他地方的不一样、不一样、不一样。具体的看下面的说明。 现在网络上同样的资源包都是用的加密带后门的主题&…

[C++11#47] (四) function包装器 | bind 函数包装器 | 结合使用

目录 一. function包装器 1. 在题解上 2.bind 绑定 1.调整参数顺序 2.对类中函数的包装方法 一. function包装器 function包装器也叫作适配器。C中的function本质是一个类模板&#xff0c;也是一个包装器。 那么我们来看看&#xff0c;我们为什么需要function呢&#xff1…

[数据集][目标检测]机油泄漏检测数据集VOC+YOLO格式43张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;43 标注数量(xml文件个数)&#xff1a;43 标注数量(txt文件个数)&#xff1a;43 标注类别数…

基于SSM的献血管理系统设计与实现(论文+源码)_kaic

摘 要 近年来&#xff0c;随着科技的飞速发展&#xff0c;在全球经济一体化的大背景下&#xff0c;我们面临着巨大的挑战&#xff0c;互联网技术将进一步提高社会综合发展的效率和速度&#xff0c;而且也会涉及到各个领域。献血管理系统在网络背景下有着无法忽视的作用&#x…

Xilinx FPGA 原语解析(三):OBUFDS差分输出缓冲器(示例源码及仿真)

目录 前言&#xff1a; 一、原语使用说明 二、原语实例化代码模版 三、使用示例 1.设计文件代码 2.仿真文件代码 3.仿真结果 前言&#xff1a; 主要参考 Xilinx 官方文档《Xilinx 7 Series FPGA and Zynq-7000 All Programmable SoC Libraries Guide for HDL Designs》…

网络工程师学习笔记——局域网和城域网(二)

快速以太网 快速以太网&#xff08;&#xff18;&#xff10;&#xff12;.&#xff13;&#xff55; &#xff11;&#xff10;&#xff10;&#xff2d;&#xff42;&#xff50;&#xff53;&#xff09; 其中多模光纤的芯线直径为&#xff16;&#xff12;.&#xff15;…

跟李沐学AI:循环神经网络RNN

循环神经网络 循环神经网络&#xff08;recurrent neural networks&#xff0c;RNNs&#xff09; 是具有隐状态的神经网络。RNN 具有隐状态&#xff08;hidden state&#xff09;的原因在于它需要一种机制来存储之前输入的信息&#xff0c;以便于处理当前输入时能够考虑之前的…

Linux教程8:文本编辑命令vi

一、文本编辑命令介绍 vi&#xff08;Visual Interface&#xff09;是一种广泛使用的文本编辑器&#xff0c;特别是在Unix和类Unix系统&#xff08;如Linux&#xff09;中。尽管现代系统通常提供了更现代的文本编辑器&#xff08;如vim&#xff0c;它是vi的增强版本&#xff0…

vue axios发送post请求跨域解决

跨越解决有两种方案&#xff0c;后端解决&#xff0c;前端解决。后端解决参考Django跨域解决-CSDN博客 该方法之前试着可以的&#xff0c;但是复制到其他电脑上报错&#xff0c;所以改用前端解决 1、main.js做增加如下配置 import axios from axios Vue.prototype.$axios a…

Spring1~~~

快速入门 javaBean规范要有set方法&#xff0c;底层反射赋值 <!-- id表示在该java对象在spring容器中的id--><bean class"spring.bean.Monster" id"monster01"><property name"Id" value"100"/><property nam…

Unity数据持久化 之 向文件流读写(详细Plus版)

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正​​ 在 Unity 手册中&#xff0c;FileStream 并没有单独的详细介绍&#xff0c;因为它是 .NET 框架的一部分&#xff0c;…