第八层:模板

news2024/9/23 7:21:11

文章目录

  • 前情回顾
  • 模板
    • 模板的概念
    • 模板的特点
    • 模板分类
    • 函数模板
      • 作用
      • 语法
      • 函数模板的使用
        • 注意事项
    • 普通函数和函数模板的区别
    • 普通函数和函数模板的调用规则
      • 优先调用普通函数
      • 空模板强调函数模板
      • 函数模板可以发生重载
      • 函数模板产生更好的匹配时
    • 模板的局限性
    • 类模板
      • 作用
      • 语法
      • 类模板实例化对象
      • 类模板与函数模板的区别
        • 自动类型推导验证
        • 类模板参数列表中可以具有默认参数
      • 类模板中成员函数的创建时机
    • 类模板对象做函数参数
      • 指定传入类型
      • 参数模板化
      • 将对象模型进行模板化
    • 类模板和继承
      • 第一点和第二点
      • 灵活指出父类中的类型
    • 类模板成员函数类外实现
    • 类模板的分文件编写
    • 类模板和友元
      • 类内实现
      • 类外实现
    • 注意
  • 第九层...顶层?

🎉welcome🎉
✒️博主介绍:一名大一的智能制造专业学生,在学习C/C++的路上会越走越远,后面不定期更新有关C/C++语法,数据结构,算法,Linux,ue5使用,制作游戏的心得,和大家一起共同成长。
✈️C++专栏:C++爬塔日记
😘博客制作不易,👍点赞+⭐收藏+➕关注

前情回顾

在上一层中,我遇到了面向对象的最后一个特性——多态,使用多态可以让代码组织结构更加情绪,使可读性变强,利于程序的前期和后期的扩展和维护,掌握多态之后,面向对象结束了, 后面会是什么呢…

  • 🚄上章地址:第七层:多态

模板

上到了第八层,映入眼帘的是一个巨大的石碑,“你来了,在C++中,除了面向过程编程和面向对象编程以外,还有一种编程思想,叫做泛型编程,泛型编程主要通过模板实现,这层就需要你掌握模板的力量…"。

模板的概念

  • 模板就是建立一个通用的模具,大大提高复用性,比如PPT模板、空白的学生证,这些东西都有一些特点,不能直接使用,需要使用者去添加一些东西,而且不是通用的,比如这个PPT模板是做年度总结的,那就不能强套到一些和年度总结不着边的东西上,因此可以总结出模板的特点。

模板的特点

  1. 模板只是一个框架
  2. 这个框架不是万能的

模板分类

在C++中模板分为两类:

  • 函数模板
  • 类模板

函数模板

作用

  • 建立一个通用函数,其函数的返回类型和形参可以不具体制定,用一个虚拟的类型来代表

语法

函数模板的语法为:

  • templatte< typename T>
    函数的声明或者定义

解释:

  • template:声明创建函数模板
  • typename:表明其后面的符号是一种通用的数据类型,可以用class替代。
  • T:通用的数据类型,可以替换成别的字母

可以尝试写一个函数模板:

#include<iostream>
using namespace std;

template<typename T>
void print(T a)
{
	cout << a << endl;
}
int main()
{


	return 0;
}

在这里插入图片描述
可以正常跑起来,那函数模板怎么使用呢?

函数模板的使用

  1. 自动类型推导:直接传入类型,让编译器自己识别是什么类型
  2. 显示制定类型:告诉编译器是什么类型,语法如下:
    函数名< 是什么数据类型 >(参数)

验证一下两种使用方法:

  • 自动类型推导
#include<iostream>
using namespace std;

template<typename T>
void print(T a)
{
	cout << a << endl;
}
void test1()
{
	print(1);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

  • 显示指定类型
#include<iostream>
using namespace std;

template<typename T>
void print(T a)
{
	cout << a << endl;
}
void test1()
{
	print<int>(1);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

注意事项

  1. 自动类型推导必须推导出一致的数据类型才可以使用
  2. 模板必须确定出T的数据类型,才可以使用

第一点解释:

#include<iostream>
using namespace std;

template<typename T>
void print(T a,T b)
{
	cout << a << endl;
}
void test1()
{
	int a = 0;
	char b = 0;
	print(a,b);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
可以看到,一个int的类型和一个char类型的数据,两个类型就不一致,这个时候,T不知道自己应该是什么,所以报错,说明对于自动类型推导就需要让两个类型一致,那显示指定类型呢?

#include<iostream>
using namespace std;

template<typename T>
void print(T a,T b)
{
	cout << a << b << endl;
}
void test1()
{
	int a = 0;
	char b = 0;
	print<int>(a,b);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
显示指定类型就可以使用。

第二点解释:
当函数模板没有参数的时候,可以直接调用吗?

#include<iostream>
using namespace std;

template<typename T>
void print()
{
	cout << "hello world" << endl;
}
void test1()
{
	print();
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
是不可以直接调用的,因为使用函数模板时,必须人编译器知道通用数据类型是什么,就算没有参数,也需要,这个时候可采用显示指定类型,不管是什么类型,都能跑去来:

#include<iostream>
using namespace std;

template<typename T>
void print()
{
	cout << "hello world" << endl;
}
void test1()
{
	print<int>();
	print<char>();
	print<double>();
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

普通函数和函数模板的区别

  • 普通函数调用可以发生自动类型转换(隐式类型转换)
  • 函数模板在调用时,如果利用自动类型推导,不会发生隐式类型转换
  • 如果利用显示指定类型,可以发生隐式类型转换

普通函数:

#include<iostream>
using namespace std;

int Swap(int a, int b)
{
	return a + b;
}

void test1()
{
	int a = 20;
	char b = '1';
	int c=Swap(a, b);
	cout << c << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
c是69,这是因为发生了隐式类型转换,char转换成了int,同时这是字符1的ASCII码值为49,49加20,就是69。
函数模板:
自动类型推导在上面的注意事项说到,必须推导出统一的数据类型才能跑起来,所以这个时候传两个类型不同的一定是会报错的,就不进行验证了,这个时候试着用显示指定类型试试:

#include<iostream>
using namespace std;

template<typename T>
int Swap(T a, T b)
{
	return a + b;
}

void test1()
{
	int a = 20;
	char b = '1';
	int c=Swap<int>(a, b);
	cout << c << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
这个时候,编译器会将参数内的所有数视为int类型的,就发生了隐式类型转换。

普通函数和函数模板的调用规则

  1. 如果函数模板和普通函数都可以实现时,优先调用普通函数
  2. 可以通过空模板参数来强调函数模板,让使用函数模板
  3. 函数模板可以发生重载
  4. 如果函数模板可以产生更好的匹配,就使用函数模板

优先调用普通函数

#include<iostream>
using namespace std;

template<typename T>
int Add(T a, T b)
{
	cout << "函数模板调用" << endl;
	return a + b;
}

int Add(int a, int b)
{
	cout << "普通函数调用" << endl;
	return a + b;
}

void test1()
{
	int a = 20;
	int b = 20;
	int c=Add(a, b);
	cout << c << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
可以发现两个函数实现内容相同,但是优先调用的普通函数。

空模板强调函数模板

  • 空模板的语法:函数名<>(传参)
#include<iostream>
using namespace std;

template<typename T>
int Add(T a, T b)
{
	cout << "函数模板调用" << endl;
	return a + b;
}

int Add(int a, int b)
{
	cout << "普通函数调用" << endl;
	return a + b;
}

void test1()
{
	int a = 20;
	int b= 20;
	int c=Add<>(a, b);
	cout << c << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
这个时候就调用了函数模板了,就是空模板起的作用,可以强制调用模板。

函数模板可以发生重载

#include<iostream>
using namespace std;

template<typename T>
int Add(T a, T b)
{
	return a + b;
}
template<typename T>
int Add(T a, T b, T c)
{
	return a + b + c;
}

void test1()
{
	int a = 20;
	int b= 20;
	int c = 20;
	int d = Add<>(a, b, c);
	cout << d << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

函数模板产生更好的匹配时

  • 当普通函数要发生类型转换,但模板可以直接调用的时候,就会调用函数模板
#include<iostream>
using namespace std;

template<typename T>
void print(T a, T b)
{
	cout << "调用函数模板" << endl;
}

void print(int a, int b)
{
	cout << "调用普通函数" << endl;
}

void test1()
{
	char a = 0;
	char b = 0;
	print(a, b);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
这个时候如果时调用普通函数,就会发生隐式类型调用,这个时候用函数模板就不需要,就调用函数模板。

模板的局限性

  • 模板的通用性不是万能的,比如要进行交换操作的时候,如果传参的是数组或者对象的时候,可以调用吗?
#include<string>
#include<iostream>
using namespace std;

template<typename T>
void Swap(T &a, T &b)
{
	T tmp = a;
	a = b;
	b = tmp;
}
class A
{
public:
	A(string a, int b)
	{
		_name = a;
		_age = b;
	}
	string _name;
	int _age;
};

void test1()
{
	A c1("zhangsan", 19);
	A c2("lisi",20);
	Swap(c1, c2);
	cout << c1._name << "的年龄" << c1._age << endl;
	cout << c2._name << "的年龄" << c2._age << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
发现并不能实现交换,那对于这些特殊的类型,怎么才可以进行呢?操作符重载吗?试一试:

#include<string>
#include<iostream>
using namespace std;

class A
{
public:
	A(string a, int b)
	{
		_name = a;
		_age = b;
	}
	void operator=(A& a)
	{
		_name =a._name;
		_age = a._age;
	}
	string _name;
	int _age;
};
template<typename T>
void Swap(T &a, T &b)
{
	T tmp = a;
	a = b;
	b = tmp;
}

void test1()
{
	A c1("zhangsan", 19);
	A c2("lisi", 20);
	Swap(c1, c2);
	cout << c1._name << "的年龄" << c1._age << endl;
	cout << c2._name << "的年龄" << c2._age << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
操作符重载是可以的,那还有没有方法呢?这个时候可以具体化一个类的版本实现,这个时候具体化是优先调用的,那具体化的语法是什么呢?语法:

  • template< > 返回类型 函数模板名 (参数的数据类型为类名)
#include<string>
#include<iostream>
using namespace std;

template<typename T>
void Swap(T& a, T& b)
{
	T tmp = a;
	a = b;
	b = tmp;
}

class A
{
public:
	A(string a, int b)
	{
		_name = a;
		_age = b;
	}
	string _name;
	int _age;
};
template< > void Swap(A& c1, A& c2)
{
	string tmp1 = c1._name;
	c1._name = c2._name;
	c2._name = tmp1;
	int tmp2 = c1._age;
	c1._age = c2._age;
	c2._age = tmp2;
}
void test1()
{
	A c1("zhangsan", 19);
	A c2("lisi", 20);
	Swap(c1, c2);
	cout << c1._name << "的年龄" << c1._age << endl;
	cout << c2._name << "的年龄" << c2._age << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
也是可以实现。

类模板

作用

  • 建立一个通用类,类内成员的数据类型不可具体定义,用一个通用的类型来代表

语法

那类模板的语法是什么?语法如下:

  • template< typename T>

因为类内会有多个数据类型,可以定义多个通用的数据类型,那尝试写一个类模板出来:

#include<iostream>
using namespace std;

template<typename T1, typename T2>
class A
{
public:
	T1 _a;
	T2 _b;
};
int main()
{
	return 0;
}

在这里插入图片描述
是可以正常跑起来的,那怎么使用这个类模板实例化一个对象出来呢?

类模板实例化对象

实例化对象的语法:

  • 类名< 数据类型(为模板参数列表) > 对象名

那选择通过一个类模板实例化出一个对象:

#include<iostream>
using namespace std;

template<typename T1, typename T2>
class A
{
public:
	T1 _a;
	T2 _b;
};
void test1()
{
	A<int, char> a1;
	a1._a = 10;
	a1._b = 'a';
	cout << a1._a << endl;
	cout << a1._b << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

类模板与函数模板的区别

  1. 类模板没有自动类型推导的使用方式
  2. 类模板在模板参数列表中可以具有默认参数

自动类型推导验证

#include<iostream>
using namespace std;

template<typename T1, typename T2>
class A
{
public:
	T1 _a;
	T2 _b;
};
void test1()
{
	A< > a1;
	a1._a = 10;
	a1._b = 'a';
	cout << a1._a << endl;
	cout << a1._b << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
报错了,跑不起来,是不可以用的。

类模板参数列表中可以具有默认参数

这个是什么意思呢?这里用代码证明:

#include<iostream>
using namespace std;

template<typename T1=int, typename T2=char>
class A
{
public:
	T1 _a;
	T2 _b;
};
void test1()
{
	A< > a1;
	a1._a = 10;
	a1._b = 'a';
	cout << a1._a << endl;
	cout << a1._b << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
这个代码和上面的代码的区别在哪?
在这里插入图片描述
看到,在模板的参数列表中,给通用数据类型进行了赋值,让它具有了默认数据类型,这个时候就可以在实例化对象的时候,不用写数据类型,用默认的数据类型,也可以在改数据类型:

#include<string>
#include<iostream>
using namespace std;

template<typename T1=int, typename T2=char>
class A
{
public:
	T1 _a;
	T2 _b;
};
void test1()
{
	A<double,string > a1;
	a1._a = 10.0;
	a1._b = "abcd";
	cout << a1._a << endl;
	cout << a1._b << endl;
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

类模板中成员函数的创建时机

  • 普通类的成员函数会在一开始就创建,类模板中的成员函数在应用时才会创建,对于类模板中调用其他类的时候的成员函数,在确认数据类型前,可以进行编译,没有问题,但是否调用成功时在确定数据类型后

代码验证:

#include<iostream>
using namespace std;

class A1
{
public:
	void print1()
	{
		cout << "A1在被调用" << endl;
	}
};
class A2
{
public:
	void print2()
	{
		cout << "A2在被调用" << endl;
	}
};
template<class T>
class A
{
public:
	void print1()
	{
		T a;
		a.print1();
	}
	void print2()
	{
		T a.print2();
	}
};
void test1()
{
	A<A1> a;
	a.print1();
	a.print2();
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
代码在没有运行的时候,没有报错,在运行之后,会发现内部编译错误,是因为通用类型被定义为A1,A1中没有print2函数,现在注释掉,在来看看:

#include<iostream>
using namespace std;

class A1
{
public:
	void print1()
	{
		cout << "A1在被调用" << endl;
	}
};
class A2
{
public:
	void print2()
	{
		cout << "A2在被调用" << endl;
	}
};
template<class T>
class A
{
public:
	void print1()
	{
		T a;
		a.print1();
	}
	//void print2()
	//{
	//	T a.print2();
	//}
};
void test1()
{
	A<A1> a;
	a.print1();
	//a.print2();
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
可以调用,这就是因为在确定通用类型之前没有生成内部函数,在确定好之后,会创建成员函数。

类模板对象做函数参数

  • 类模板实例化出来的对象,可以做函数的参数吗?可以而且方法还不少:
  1. 指定传入类型:直接显示对象的数据类型
  2. 参数模板化:将对象中的参数变成模板进行传递
  3. 整个类模板化:将整个对象模型模板化进行传递

指定传入类型

指定传入类型怎么去做?下面用代码来演示:

#include<string>
#include<iostream>
using namespace std;

template<class T1,class T2>
class per
{
public:
	per(T1 a, T2 b)
	{
		_name = a;
		_age = b;
	}
	T1 _name;
	T2 _age;
};
void print(per<string, int> p)
{
	cout << p._name << "的年龄" << p._age << "岁" << endl;
}

void test1()
{
	per<string, int> p("张三",18);
	print(p);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
直接将对象名前面的类名和模板的数据类型传过去就可以。

参数模板化

参数模板化,顾名思义,就是将参数变成和模板一样,模板有什么特点?通用的数据类型,就其实就是将模板的参数列表变成通用的数据类型即可:

#include<string>
#include<iostream>
using namespace std;

template<class T1,class T2>
class per
{
public:
	per(T1 a, T2 b)
	{
		_name = a;
		_age = b;
	}
	T1 _name;
	T2 _age;
};
template<class T1,class T2>
void print(per<T1,T2> p)
{
	cout << p._name << "的年龄" << p._age << "岁" << endl;
}

void test1()
{
	per<string, int> p("张三",18);
	print(p);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

将对象模型进行模板化

将对象模型进行模板化,就是将对象变成一个通用类型:

#include<string>
#include<iostream>
using namespace std;

template<class T1,class T2>
class per
{
public:
	per(T1 a, T2 b)
	{
		_name = a;
		_age = b;
	}
	T1 _name;
	T2 _age;
};
template<class T>
void print(T p)
{
	cout << p._name << "的年龄" << p._age << "岁" << endl;
}

void test1()
{
	per<string, int> p("张三",18);
	print(p);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

类模板和继承

既然都是类,那类模板可以作为父类吗?被继承吗?是可以的,但是有需要注意的地方:

  1. 当子类继承的父类是一个类模板的时候,子类在声明的时候,要指出父类中通用类型的类型
  2. 如果不指定,编译器无法给子类分配内存
  3. 如果想灵活的指出父类中通用类型的类型,子类也需要变成类模板

第一点和第二点

  • 因为在子类中会继承父类中的所有非静态成员变量,这个时候如果不知道父类中成员是什么类型,则编译器不知道应该分配多少内存给子类当中,所以要指定出来,那怎么指定呢?写法:
  • class 子类 : 继承方式 父类< 指定出类型 >

代码验证:

#include<iostream>
using namespace std;

template<class T1,class T2>
class per
{
public:
	per(T1 a, T2 b)
	{
		_name = a;
		_age = b;
	}
	T1 _name;
	T2 _age;
};
class per1 :public per
{
public:

};
int main()
{
	return 0;
}

在这里插入图片描述这个时候没有写,报错。

#include<string>
#include<iostream>
using namespace std;

template<class T1,class T2>
class per
{
public:
	per(T1 a, T2 b)
	{
		_name = a;
		_age = b;
	}
	T1 _name;
	T2 _age;
};
class per1 :public per<string ,int>
{
public:

};
int main()
{
	return 0;
}

在这里插入图片描述
写上之后不报错。

灵活指出父类中的类型

那怎么样才能灵活的指出呢?这个时候将子类变成模板即可:

#include<string>
#include<iostream>
using namespace std;

template<class T1,class T2>
class per
{
public:
	per(T1 a, T2 b)
	{
		_name = a;
		_age = b;
	}
	T1 _name;
	T2 _age;
};
template<class T,class T1>
class per1 :public per<T,T1>
{
public:

};
int main()
{
	return 0;
}

在这里插入图片描述
这个时候,这个T和T1就指向的是父类中的两个通用模板:
在这里插入图片描述

类模板成员函数类外实现

  • 普通类的成员函数可以在类外实现,那类模板的是否可以?是可以的,有一定的语法格式,不仅仅要加作用域:
  • template < class T >
    返回类型 类名< 参数 >:: 函数名 (T ____)

构造函数也可以进行类外实现,用代码验证一下:

#include<string>
#include<iostream>
using namespace std;

template<class T1,class T2>
class per
{
public:
	per(T1 a, T2 b);
	T1 _name;
	T2 _age;
};
template<class T1,class T2>
per<T1, T2>::per(T1 a, T2 b)
{
	_name = a;
	_age = b;
	cout << _name << "的年龄为" << _age << endl;
}
void test1()
{
	per<string, int>p("张三", 18);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

类模板的分文件编写

  • 当代码量过大时,程序员通常会选择分文件编写,将声明实现和调用分开,那模板分开可以正常使用吗?

验证:

  • test.cpp
#include"per.h"

void test1()
{
	per<string, int>p("张三", 18);
}
int main()
{
	test1();
	return 0;
}
  • per.cpp
#include"per.h"
template<class T1, class T2>
class per
{
public:
	per(T1 a, T2 b)
	{
		_name = a;
		_age = b;
		cout << _name << "的年龄为" << _age << endl;
	}
	T1 _name;
	T2 _age;
};
  • per.h
#pragma once

#include<string>
#include<iostream>
using namespace std;
template<class T1, class T2>
class per;

在这里插入图片描述

是报错的,那这是为什么?上面说到,对于类模板中的成员函数在编译器阶段才去创建的,我们包含的头文件,那这个时候编译器就不会看到实现部分,只看到了声明,那这个时候可以将引的头文件该成实现的模块:

#include"per.cpp"

void test1()
{
	per<string, int>p("张三", 18);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述
是可以正常使用的,那这个时候还可以将声明和实现放在一起,任何将后缀改为hpp,其他也可以,只是hpp是约定俗成的,一看上去就知道是模板的实现和定义。

类模板和友元

  • 那类模板可以有友元函数吗?是可以拥有的,分为类内实现和类外实现

类内实现

类内实现直接在类捏将函数功能实现出来即可:

template<class T1,class T2>
class per
{
	friend void print(per<T1, T2> &p)
	{
		cout << _name << "的年龄为" << _age << endl;
	}
public:
	per(T1 a, T2 b)
	{
		_name = a;
		_age = b;
	}
private:
	string _name;
	int _age;
};

类外实现

template<class T1,class T2>
class per
{
	friend void print< >(per<T1, T2>& p);
public:
	per(T1 a, T2 b)
	{
		_name = a;
		_age = b;
	}
private:
	string _name;
	int _age;
};

类外实现时要注意,需要提前让编译器知道它存在,所以声明在类模板中。

注意

  • 掌握模板不是为了写模板,而是为了使用第九层中的stl。

第九层…顶层?

看完上面的内容,我便踏入了前往第九层的楼梯,上来之后,抬头便是许久未见的天空…

😘预知后事如何,关注新专栏,和我一起征服C++这座巨塔
🚀专栏:C++爬塔日记
🙉都看到这里了,留下你们的👍点赞+⭐收藏+📋评论吧🙉

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

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

相关文章

Redis在秒杀场景的作用

秒杀业务特点&#xff1a;限时限量&#xff0c;业务系统要处理瞬时高并发请求&#xff0c;Redis是必需品。 秒杀可分成秒杀前、秒杀中和秒杀后三阶段&#xff0c;每个阶段的请求处理需求不同&#xff0c;Redis具体在秒杀场景的哪个环节起到作用呢&#xff1f; 1 秒杀负载特征…

Java-数据结构-二叉树<三>

承接上文&#xff1a; Java-数据结构-二叉树&#xff1c;一&#xff1e; Java-数据结构-二叉树&#xff1c;二&#xff1e; 一. 二叉树的简单介绍 见Java-数据结构-二叉树&#xff1c;一&#xff1e; 二. 二叉树的典型代码实现 见Java-数据结构-二叉树&#xff1c;一&#x…

4. RNN网络架构解读|词向量模型|模型整体框架|训练数据构建|CBOW和Skip-gram模型|负采样方案

文章目录RNN网络架构解读词向量模型模型整体框架训练数据构建CBOW和Skip-gram模型负采样方案RNN网络架构解读 递归神经网络实际上就是普通的神经网络的部分进行修改更新&#xff1a;实际上常用于时间序列的更新。或者就是自然处理中 X序列代表着时间序列&#xff0c;x0是一个时…

linux入门---云服务器购买和登陆

目录标题云服务器选择云服务器购买xshell下载如何登陆云服务器Linux的新建与删除新建删除云服务器选择 学习linux的时候云服务器是一个非常重要的工具&#xff0c;那么我们在购买云服务器的时候有很多选择比如说&#xff1a;华为云&#xff0c;腾讯云&#xff0c;阿里云等等&a…

【实操案例十二】类和对象 实例代码及运行效果图!

任务一&#xff1a;定义一个圆的类&#xff0c;计算面积和周长 # 任务一&#xff1a;定义一个圆的类&#xff0c;计算面积和周长 import math class Circle():def __init__(self,r):self.rrdef get_area(self):return math.pi*r*rdef get_perimeter(self):return 2*math.pi*r …

初识 ThreeJS (ThreeJS 相关环境搭建)

初识 ThreeJS &#xff08;初识 ThreeJS &#xff08;ThreeJS 相关环境搭建&#xff09;参考描述ThreeJS在本地搭建 NodeJS 的官方网站获取使用安装依赖项运行官方文档案例场景编辑器搭建 ThreeJS 运行环境webpack项目结构package.jsonwebpack.config.js深入获取检测参考 项目…

袋式除尘器—分类和命名

按除尘器的结构形式分类(1)按滤袋开头分类按滤袋形状分类&#xff0c;可分为圆袋式除尘器和扁袋式除尘器两类。①圆袋式除尘器。滤袋形状为圆筒形&#xff0c;直径一般为120&#xff5e;300mm&#xff0c;最大不超过600mm&#xff1b;高度为2&#xff5e;3m&#xff0c;也有10m…

redis 数据库简介

一 概述 redis是一种nosql数据库,他的数据是保存在内存中&#xff0c;同时redis可以定时把内存数据同步到磁盘&#xff0c;即可以将数据持久化&#xff0c;并且他比memcached支持更多的数据结构(string,list列表[队列和栈],set[集合],sorted set[有序集合],hash(hash表))。相关…

2023年哪款手机浏览器比较好用,最后一个吹爆它

很多人不满足于手机自带的浏览器&#xff0c;为了更好地满足看视频、浏览网页、看小说等需求&#xff0c;不少人下载第三方手机浏览器来使用。我们都知道&#xff0c;手机浏览器是手机不可缺少的APP之一。那么&#xff0c;2023年哪款手机浏览器比较好用&#xff1f;下面分享今年…

Java File类及案例

File概述和构造方法 File对象就表示一个路径&#xff0c;可以是文件路径、也可以是文件夹的路径这个路径可以是存在的&#xff0c;也允许是不存在的 方法名称说明public File (String pathname)把字符串表示的路径变成File对象public File (Srting parent, String child)把父…

【My Electronic Notes系列——三极管】

目录 序言&#xff1a; &#x1f3ee;&#x1f3ee;新年的钟声响&#xff0c;新年的脚步迈&#xff0c;祝新年的钟声&#xff0c;敲响你心中快乐的音符&#xff0c;幸运与平安&#xff0c;如春天的脚步紧紧相随&#xff0c;春节快乐&#xff01;春华秋实&#xff0c;我永远与你…

C语言入门(八)——数组

数组的基本概念 数组应用实例:统计随机数 数组应用实例:直方图 字符串 多维数组 数组的基本概念 数组(Array)也是一种复合数据类型&#xff0c;它由一系列相同类型的元素(Element)组成。例如定义一个由4个int型元素组成的数组count: int count[4]; 和结构体成员类似&…

安卓S开机动画流程

安卓S开机动画流程 开机动画是在SurfaceFlinger实例通过调用startBootAnim()启动的&#xff0c;BootAnim是如何启动和结束的&#xff0c;总体框架图如下&#xff1a; 1.SurfaceFlinger进程启动 # /frameworks/native/services/surfaceflinger/surfaceflinger.rc service surf…

linux inode详解

1.inode 和 block 概述. 操作系统的文件数据除了实际内容之外&#xff0c;通常含有非常多的属性&#xff0c;例如Linux操作系统的文件权限与文件属性。文件系统通常会将这两部分内容分别存放在inode和block中。 文件是存储在硬盘上的&#xff0c;硬盘的最小存储单位叫做扇区sec…

行为型模式

1.模版方法 超类中定义了一个算法的框架&#xff0c; 允许子类在不修改结构的情况下重写算法的特定步骤 结构 抽象类&#xff1a;负责给出一个轮廓与骨架&#xff0c;由一个模版方法和若干个基本方法构成 模版方法&#xff1a;按某种顺序调用其包含的基本方法基本方法&#xf…

计算机视觉OpenCv学习系列:第八部分、图像操作-4

第八部分、图像操作-4第一节、图像卷积操作1.图像卷积定义2.卷积函数3.代码练习与测试第二节、高斯模糊1.高斯模糊2.函数解释3.代码练习与测试第三节、像素重映射1.像素重映射定义2.重映射函数3.代码练习与测试学习参考第一节、图像卷积操作 1.图像卷积定义 卷积的基本原理&am…

java spring IOC xml 方式 内部Bean注入

上次说了外部 Bean注入 这次来演示一个内部的 Bean注入 我们先创建一个spring 项目 导入最基本的 spring 包 在项目src目录下创建一个包 cascade cascade包下创建两个类 Dept 部门类 参考代码如下 package cascade;//部门类 public class Dept {private String dname;publi…

windows ssdt

前言 我们 ring 3 跳转 ring0 另一种方式使用sysenter命令。 sysenter 相比起jmp,int xx方式相比速度更快&#xff0c;因为sysenter指令大量的使用了MSR寄存器 存储跳转地址等。 MSR寄存器相关读/写命令 //读取msr寄存器 rdmsr xxxx //写入msr寄存器 wrmsr xxxx其中xxx是ms…

轻量实时操作系统学习(一)

306xH系列产品基于高性能RISC-V CPU核&#xff0c;工作频率最高到200MHz&#xff0c;集成了FPU浮点处理单元&#xff0c;支持浮点乘法&#xff0c;支持浮点乘法&#xff0c;除法和开方等复杂数学运算指令&#xff0c;支持16KB的SRAM和最高160KB的flash存储单元。 该MCU集成最多…

【My Electronic Notes系列——二极管】

目录 序言&#xff1a; &#x1f3ee;&#x1f3ee;新年的钟声响&#xff0c;新年的脚步迈&#xff0c;祝新年的钟声&#xff0c;敲响你心中快乐的音符&#xff0c;幸运与平安&#xff0c;如春天的脚步紧紧相随&#xff0c;春节快乐&#xff01;春华秋实&#xff0c;我永远与…