模板
类模板对象做函数参数
一共有三种传入方式:
-
指定传入的类型---直接显示对象的数据类型
-
参数模板化---将对象中的参数变为模板进行传递
-
整个类模板化---将这个对象类型,模板化进行传递
-
其实用的最多的还是第一个
实例:
#include <iostream> #include <string> using namespace std; template<class T1 , class T2> class Person { public: Person(T1 name , T2 age) { this->m_Name = name; this->m_Age = age; } void showPerson() { cout << "name: " << m_Name << " age: " << m_Age << endl; } T1 m_Name; T2 m_Age; };
//第一种方式:指定传入的类型---直接显示对象的数据类型
void printPerson1(Person<string, int>&p) { p.showPerson(); } void test01() { Person<string, int>p = {"张三" , 18}; printPerson1(p); }
//第二种方式:参数模板化---将对象中的参数变为模板进行传递
template<class T1 , class T2> void printPerson2(Person<T1, T2>& p) { p.showPerson(); } void test02() { Person<string, int>p = { "张三" , 18 }; printPerson2(p); }
//第三种方式:整个类模板化---将这个对象类型,模板化进行传递
template<class T> void printPerson3(T& p) { p.showPerson(); } void test03() { Person<string, int>p = { "张三" , 18 }; printPerson3(p); } int main() { //test01(); //test02(); test03(); system("pause"); return 0; }
类模板与继承
当类模板碰到继承时,需要注意以下几点:
-
当子类继承的父类是一个类模板时。子类在声明的时候,要指定出父类中T的类型
-
如果不指定,编译器无法给子类分配内存
-
如果想灵活指定出父类中T的类型,子类也需变为类模板
示例:
类模板成员函数类外实现
#include <iostream>
#include <string>
using namespace std;
template<class T1 , class T2>
class Person
{
public:
Person(T1 name, T2 age);
void showPerson();
T1 m_Name;
T2 m_Age;
};
template<class T1 , class T2>
Person<T1, T2>::Person(T1 name, T2 age)
{
this->m_Name = name;
this->m_Age = age;
}
template<class T1, class T2>
void Person<T1, T2>::showPerson()
{
cout << "name = " << this->m_Name << " age = " << this->m_Age << endl;
}
void test01()
{
Person<string, int>p("张三" ,18);
p.showPerson();
}
int main()
{
test01();
system("pause");
return 0;
}
类模板分文件编写
问题:
-
类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到
解决:
-
解决方式一:直接包含.cpp源文件
-
解决方式二:将声明和实现写到同一个文件中,并更改后缀名为.hpp,.hpp是约定的名称,并不是强制
类模板与友元
-
全局函数类内实现
-
全局函数类外实现
#include <iostream>
#include <string>
using namespace std;
template<class T1, class T2>
class Person;
template<class T1, class T2>
void printPerson2(Person<T1, T2>& p)
{
cout << "类外实现--- name = " << p.m_Name << " age = " << p.m_Age << endl;
}
template<class T1 , class T2>
class Person
{
//类内实现
friend void printPerson1(Person<T1, T2>& p)
{
cout << "类内实现--- name = " << p.m_Name << " age = " << p.m_Age << endl;
}
//类外实现
friend void printPerson2<>(Person<T1, T2>& p);
public:
Person(T1 name, T2 age)
{
this->m_Name = name;
this->m_Age = age;
}
private:
T1 m_Name;
T2 m_Age;
};
void test01()
{
Person<string, int>p("Tom" , 18);
printPerson1(p);
}
void test02()
{
Person<string, int>p("Tom", 18);
printPerson2(p);
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}
STL
deque容器
功能:
-
双端数组,可以对头端进行插入删除操作
deque与vector区别:
-
vector对于头部的插入效率低,数据量大,效率较低
-
deque相对而言,对头部的插入删除速度比vector快
-
vector访问元素时的速度会比deque快,这和两者内部实现有问题
deque构造函数
函数原型:
-
deque<T> deqT; //默认构造形式
-
deuqe(beg , end); //构造函数将[beg , end]区间中的元素拷贝给本身
-
deque(n , elem); // 构造函数将n个elem拷贝给本身
-
deque(const deque &deq) //拷贝构造函数
deque赋值操作
函数原型:
-
deque& operator = (const deque &deq); //重载等号操作
-
assign(beg , end); //将[beg , end]区间中数据拷贝赋值给本身
-
assign(n , elem); //将n个elem拷贝赋值给本身
deuqe大小操作
函数原型:
-
deque.empty(); //判断容器是否为空
-
deque.size(); //返回容器中元素的个数
-
deque.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除
-
deque.resize(num , elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除