十五.模板的分文件编写
代码片内有详解
例一 :
1.main.cpp Code
:
#include<iostream>
using namespace std;
// 前提: 当包含 .h 文件时 会报错,原因:函数初始化不完全
//#include "Person.h"
// 解决方法: 一. 包含 .cpp 文件 (不推荐)
//#include "Person.cpp"
// 解决方法: 二. 包含 .hpp 文件 (推荐)
// 将源文件以及头文件写入到同一文件里,并更改后缀名 .hpp
#include "Person.hpp"
void test()
{
Person<string, int> Per1("平生",234);
Per1.show();
}
int main()
{
test();
system("pause");
return 0;
}
2.Person.hpp Code
:
#pragma once
#include<iostream>
using namespace std;
template<class T1,class T2>
class Person
{
public:
Person(T1 nam,T2 ag);
void show();
T1 name;
T2 age;
};
template<class T1, class T2>
Person<T1, T2>::Person(T1 nam, T2 ag)
{
this->age = ag;
this->name = nam;
}
template<class T1, class T2>
void Person<T1, T2>::show()
{
cout << "name : " << this->name << " age : " << this->age << endl;
}
3.运行结果
:
略…
例二 :
1.main.cpp Code
:
#include<iostream>
using namespace std;
#include "person.hpp"
// 类模板案例
//案例描述 : 实现一个通用的数组类,要求如下:
//
//可以对内置数据类型以及自定义数据类型的数据进行存储
//将数组中的数据存储到堆区
//构造函数中可以传入数组的容量
//提供对应的拷贝构造函数以及operator = 防止浅拷贝问题
//提供尾插法和尾删法对数组中的数据进行增加和删除
//可以通过下标的方式访问数组中的元素
//可以获取数组中当前元素个数和数组的容量
class Person {
public:
Person() {}
Person(string name, int age) {
this->m_Name = name;
this->m_Age = age;
}
public:
string m_Name;
int m_Age;
};
void printPersonArray(M_Arry<Person>& personArr)
{
for (int i = 0; i < personArr.GetSize(); i++) {
cout << "姓名:" << personArr[i].m_Name << " 年龄: " << personArr[i].m_Age << endl;
}
}
void test()
{
M_Arry<int> arr1(5);
M_Arry<int> arr2(arr1);//拷贝函数测试
M_Arry<int> arr3(100);
arr2 = arr3;//operator = 赋值函数重载调用
for (int a = 0;a < 5;a++)
{
arr1.TailInsert(a);
//利用尾插法向数组中插入数据
}
for (int a = 0; a < 5; a++)
{
cout << "arr[" << a << "] = " << arr1[a] << endl;
//测试下标
}
arr1.TailDeletion();
arr1.TailDeletion();
arr1.TailInsert(889);
for (int a = 0; a < 5; a++)
{
cout << "arr[" << a << "] = " << arr1[a] << endl;
//测试下标
}
cout << "arr1.GetCapacity() = " << arr1.GetCapacity() << endl;
cout << "arr1.GetSize() = " << arr1.GetSize() << endl;
//创建数组
M_Arry<Person> pArray(10);
Person p1("孙悟空", 30);
Person p2("韩信", 20);
Person p3("妲己", 18);
Person p4("王昭君", 15);
Person p5("赵云", 24);
//插入数据
pArray.TailInsert(p1);
pArray.TailInsert(p2);
pArray.TailInsert(p3);
pArray.TailInsert(p4);
pArray.TailInsert(p5);
printPersonArray(pArray);
cout << "pArray的大小:" << pArray.GetSize() << endl;
cout << "pArray的容量:" << pArray.GetCapacity() << endl;
}
int main()
{
test();
system("pause");
return 0;
}
2.Person.hpp Code
:
#pragma once
#include<iostream>
using namespace std;
template<class T>
class M_Arry
{
public:
//构造函数中可以传入数组的容量
M_Arry(int Capa) //
{
cout << "M_Arry 有参构造调用" << endl;
this->A_Capacity = Capa;
this->A_Size = 0;
this->A_A = new T[this->A_Capacity];
//在堆区开辟一个类型为 T Capacity is Capa 的数组
}
//提供对应的拷贝构造函数以及operator = 防止浅拷贝问题
//拷贝构造函数
M_Arry(const M_Arry & M1)
{
cout << "M_Arry 拷贝构造函数调用" << endl;
this->A_Capacity = M1.A_Capacity;
this->A_Size = M1.A_Size;
this->A_A = new T[this->A_Capacity];
for (int q = 0; q < this->A_Size; q++)
{
//如果T为对象,而且还包含指针,必须需要重载 = 操作符,因为这个等号不是 构造 而是赋值,
// 普通类型可以直接= 但是指针类型需要深拷贝
this->A_A[q] = M1.A_A[q];
}
}
M_Arry& operator = (const M_Arry& M1)
{
cout << "M_Arry 赋值重载函数调用" << endl;
if (A_A != NULL)
{
delete[] this->A_A;
this->A_A = NULL;
this->A_Capacity = 0;
this->A_Size = 0;
}
this->A_Capacity = M1.A_Capacity;
this->A_Size = M1.A_Size;
this->A_A = new T[this->A_Capacity];
for (int q = 0; q < this->A_Size; q++)
{
//如果T为对象,而且还包含指针,必须需要重载 = 操作符,因为这个等号不是 构造 而是赋值,
// 普通类型可以直接= 但是指针类型需要深拷贝
this->A_A[q] = M1.A_A[q];
}
return *this;
}
//尾插法
void TailInsert(const T& ad)
{
if (this->A_Capacity == this->A_Size)
{
cout << "数组容量已满" << endl;
return;
}
this->A_A[this->A_Size] = ad;
this->A_Size++;
}
//尾删法
void TailDeletion()
{
if (this->A_Size == 0)
{
cout << "数组已清空" << endl;
return;
}
A_A[A_Size - 1] = 0;
this->A_Size--;
}
// 通过下标访问数组 重载[]号 arr[0] = 100; 作为左值存在? 返回引用即可
T& operator [] (int in)
{
//cout << "重载[]号" << endl;
return this->A_A[in];
}
// 返回数组容量
int GetCapacity()
{
return this->A_Capacity;
}
//返回数组大小
int GetSize()
{
return this->A_Size;
}
//析构函数
~M_Arry()
{
cout << "M_Arry 析构函数调用" << endl;
if (A_A != NULL)
{
delete[] this->A_A;
this->A_A = NULL;
this->A_Capacity = 0;
this->A_Size = 0;
}
}
private:
T* A_A;//指向一个堆空间,这个空间存储真正的数据
int A_Capacity;//容量
int A_Size;//大小
};