C++中类模板的应用你了解多少

目录
  • 类模板应用
    • 数组类的封装
      • Int的.hpp文件
      • int的测试文件
      • Person类的.hpp文件
      • Person类的测试文件
  • 总结

类模板应用

数组类的封装

属性:

1,T *pAddress 指向堆区数组的指针。
2,int m_Capacity 数组容量
3,int m_Size 数组大小

行为:

1,myArray(int capacity) 构造函数
2,myArray(const MyArray&arr) 拷贝构造函数
3,operator= 重载赋值操作符=
4,operator[] 重载中括号[]
5,~myArray()  析构函数
6,getCapacity 获取容量
7,getSize     获取大小
8,pushback   尾插

将头文件与实现文件写到一起,后缀是.hpp

Int的.hpp文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<string>
template<class T>
class MyArray
{
public:
	MyArray() {};//默认构造
	MyArray(int capacity)//有参构造
	{
		this->m_Capacity = capacity;
		this->m_Size = 0;
		this->pAddress = new T[this->m_Capacity];
	}
	MyArray(const MyArray& arr)//拷贝构造
	{
		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;
		this->pAddress = new T[this->m_Capacity];//这个不能直接拷贝,需要自己重新创建
		for (int i = 0; i < arr.m_Size; i++)//然后将数组的元素一个个的赋值过来
		{
			this->pAddress[i] = arr.pAddress[i];
		}
	}
	MyArray& operator=(const MyArray &arr)//重载赋值操作符=(返回自身的引用)
	{
		if (this->pAddress)//如果原先有数据了,那么就删除
		{
			delete[] this->pAddress;
			this->pAddress = NULL;
		}
		//然后进行深拷贝
		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;
		this->pAddress = new T[this->m_Capacity];//这个不能直接拷贝,需要自己重新创建
		for (int i = 0; i < arr.m_Size; i++)//然后将数组的元素一个个的赋值过来
		{
			this->pAddress[i] = arr.pAddress[i];
		}
		return *this;
	}
	T& operator[](int dex)//重载[] 为了访问数组中的值,
	{
		return this->pAddress[dex];
	}

	void pushBack(const T& val)//尾插
	{
		if (this->m_Capacity <= this->m_Size)//如果已经超过范围了
		{
			return;
		}
		this->pAddress[this->m_Size] = val;
		this->m_Size++;
	}
	int getCapacity()//获取数组容量
	{
		return this->m_Capacity;
	}
	int getSize()//获取数组大小
	{
		return this->m_Size;
	}
	~MyArray()//析构
	{
		if (this->pAddress)
		{
			delete[] this->pAddress;
			this->pAddress = NULL;
		}
	}
private:
	T* pAddress;//指向堆区真实数组指针
	int m_Capacity;//数组容量
	int m_Size;
};

int的测试文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<string>
#include"myArray.hpp"
void myPrint(MyArray<int> &myIntArray)
{
	for (int i = 0; i < myIntArray.getSize(); i++)
	{
		cout << myIntArray[i] << endl;
	}
}
int main()
{
	MyArray<int> myIntArray(100);
	for (int i = 0; i < 10; i++)
	{
		myIntArray.pushBack(i + 100);
	}
	myPrint(myIntArray);
	return 0;
}

输出结果:

100
101
102
103
104
105
106
107
108
109

以上代码证明写的数组类的封装对内置数据类型是适用的,接下来试试自定义类型Person

ps:如果识别出来了是要开辟Person类的数组的空间,需要调用Person的默认构造(有参构造不行),所以必须在Person类中加一个默认构造。

Person类的.hpp文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<string>

template<class T>
class MyArray
{
public:
	MyArray() {};//默认构造
	MyArray(int capacity)//有参构造
	{
		this->m_Capacity = capacity;
		this->m_Size = 0;
		this->pAddress = new T[this->m_Capacity];
	}
	MyArray(const MyArray& arr)//拷贝构造
	{
		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;
		this->pAddress = new T[this->m_Capacity];//这个不能直接拷贝,需要自己重新创建
		for (int i = 0; i < arr.m_Size; i++)//然后将数组的元素一个个的赋值过来
		{
			this->pAddress[i] = arr.pAddress[i];
		}
	}
	MyArray& operator=(const MyArray &arr)//重载赋值操作(返回自身的引用)
	{
		if (this->pAddress)//如果原先有数据了,那么就删除
		{
			delete[] this->pAddress;
			this->pAddress = NULL;
		}
		//然后进行深拷贝
		this->m_Capacity = arr.m_Capacity;
		this->m_Size = arr.m_Size;
		this->pAddress = new T[this->m_Capacity];//这个不能直接拷贝,需要自己重新创建
		for (int i = 0; i < arr.m_Size; i++)//然后将数组的元素一个个的赋值过来
		{
			this->pAddress[i] = arr.pAddress[i];
		}
		return *this;
	}
	T& operator[](int dex)//重载[] 为了访问数组中的值,
	{
		return this->pAddress[dex];
	}

	void pushBack(const T& val)//尾插
	{
		if (this->m_Capacity <= this->m_Size)//如果已经超过范围了
		{
			return;
		}
		this->pAddress[this->m_Size] = val;
		this->m_Size++;
	}
	int getCapacity()//获取数组容量
	{
		return this->m_Capacity;
	}
	int getSize()//获取数组大小
	{
		return this->m_Size;
	}
	~MyArray()//析构
	{
		if (this->pAddress)
		{
			delete[] this->pAddress;
			this->pAddress = NULL;
		}
	}
private:
	T* pAddress;//指向堆区真实数组指针
	int m_Capacity;//数组容量
	int m_Size;
};

Person类的测试文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<string>
#include"myArray.hpp"
class Person
{
public:
	Person() {};
	string m_name;
	int m_age;
	Person(string name, int age)
	{
		this->m_age = age;
		this->m_name = name;
	}
};
void myPrintInt(MyArray<int> &myIntArray)//int的
{
	for (int i = 0; i < myIntArray.getSize(); i++)
	{
		cout << myIntArray[i] << endl;
	}
}
void myPrintPerson(MyArray<Person>& myPersonArray)//Person的
{
	for (int i = 0; i < myPersonArray.getSize(); i++)
	{
		cout << myPersonArray[i].m_name << " " << myPersonArray[i].m_age << endl;
	}
}
int main()
{
	/*MyArray<int> myIntArray(100);
	for (int i = 0; i < 10; i++)
	{
		myIntArray.pushBack(i + 100);
	}
	myPrintInt(myIntArray);*/
	MyArray<Person>myPersonArray(100);
	Person p1("小明", 18);
	Person p2("小宏", 18);
	Person p3("小量", 19);
	Person p4("小应", 18);
	myPersonArray.pushBack(p1);
	myPersonArray.pushBack(p2);
	myPersonArray.pushBack(p3);
	myPersonArray.pushBack(p4);
	myPrintPerson(myPersonArray);
	cout << "数组容量:"<<myPersonArray.getCapacity()<< endl;//100
	cout << "数组大小:" << myPersonArray.getSize() << endl;//4
	return 0;
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • C++实现模板中的非类型参数的方法

    非类型模板参看,顾名思义,模板参数不限定于类型,普通值也可作为模板参数.在基于类型的模板中,模板实例化时所依赖的是某一类型的模板参数,你定义了一些模板参数(template<typename T>)未加确定的代码,直到模板被实例化这些参数细节才真正被确定.而非类型模板参数,面对的未加确定的参数细节是指(value),而非类型.当要使用基于值的模板时,你必须显式地指定这些值,模板方可被实例化. 在函数模板中使用非类型参数 #include<iostream> using namesp

  • C++模板基础之函数模板与类模板实例详解

    泛型编程  如果让你编写一个函数,用于两个数的交换.在C语言中,我们会用如下方法: // 交换两个整型 void Swapi(int* p1, int* p2) { int tmp = *p1; *p1 = *p2; *p2 = tmp; } // 交换两个双精度浮点型 void Swapd(double* p1, double* p2) { double tmp = *p1; *p1 = *p2; *p2 = tmp; }  因为C语言不支持函数重载,所以用于交换不同类型变量的函数的函数名是不

  • C++使用智能指针实现模板形式的单例类

    本文通过实例为大家分享了java实现图书管理系统的具体代码,供大家参考,具体内容如下 实现一个模板形式的单例类,对于任意类型的类经过Singleton的处理之后,都能获取一个单例对象,并且可以传递任意参数 并且还使用了智能指针,把生成的单例对象托管给智能指针,从而实现自动回收单例对象的资源 此外,如果需要一个放在静态成员区的对象供其他类使用,又不希望修改原有的类的代码,这时候可以通过该模板套一层壳,形成单例对象. 头文件 template_singleton.hpp #include <iost

  • C++使用模板类实现链式栈

    本文实例为大家分享了C++使用模板类实现链式栈的具体代码,供大家参考,具体内容如下 一.实现程序: 1.Stack.h #ifndef Stack_h #define Stack_h template <class T> class Stack { public: Stack(){}; // 构造函数 void Push(const T x); // 新元素进栈 bool Pop(); // 栈顶元素出栈 virtual bool getTop(T &x) const = 0; //

  • C++ 函数模板和类模板详情

    目录 1. 泛型编程 2. 函数模板 2.1 函数模板概念 2.2 函数模板格式化 2.3 函数模板原理 2.4 函数模板实例化 2.5 模板参数的匹配原理 3. 类模板 3.1 类模板的定义格式 3.2 类模板的实例化 1. 泛型编程 如何实现一个通用的交换函数? 在C++中可以用到函数重载 class A { public: void Swap(int& x1,int& x2) { int temp=x1; x1=x2; x2=temp; } void Swap(double&

  • C++ 标准模板类详解

    目录 1 标准模板库 2.泛型编程 总结 1 标准模板库 STL提供了表示容器.迭代器.函数对象和算法的模板. 容器:类似数组存储若干值,切实同质的: 迭代器:遍历容器的对象,类似遍历数组的指针,广义指针: 算法:完成特定的任务: 函数对象:类对象或函数指针. 模板类 vector erase() 删除矢量中给定区间元素.接受两个迭代器参数(该参数定义了要删除的区间),迭代器1指向区间起始处,迭代器2指向区间终止处的后一个位置. // delete first and second elemen

  • 浅析C++中类模板的用法

    目录 C++类模板 总结 C++类模板 C++类模板是一种用于创建通用类的工具,它允许我们定义一个通用类,支持多种类型. 定义类模板 C++中定义类模板的语法如下: template<class T> class ClassName { public: ClassName(T arg1, T arg2, ...){ // constructor code } T getMax(); T getMin(); // ... private: T arg1, arg2, ...; }; 其中,tem

  • 解读C++编程中类模板的三种特化

    1.类模板显式特化 为了进行特化,首先需要一个通用的版本,称主模板.主模板使用了标准库堆算法.  堆 是一种线性化的树形结构,将一个值压入一个堆中, 实际上等于将该值插入到一个树形结构中;将一个值从堆中取出就等于移除并返回堆中最大值.但在处理字符的指针时会碰钉子.堆将按照指针的值进行组织. 我们可以提供一个显式特化版本解决此问题(例1)如果希望除了一个针对const char*的Heap外,还希望提供一个针对char *的Heap;(例2) //主模板 template <typename T>

  • 详解C++编程中类模板的相关使用知识

    有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,如下面语句声明了一个类: class Compare_int { public : Compare(int a,int b) { x=a; y=b; } int max( ) { return (x>y)?x:y; } int min( ) { return (x<y)?x:y; } private : int x,y; }; 其作用是对两个整数作比较,可以通过调用成员函数max和min得到两个整数中的大者和小者. 如果想对两个浮点数(

  • C++中类模板的应用你了解多少

    目录 类模板应用 数组类的封装 Int的.hpp文件 int的测试文件 Person类的.hpp文件 Person类的测试文件 总结 类模板应用 数组类的封装 属性: 1,T *pAddress 指向堆区数组的指针. 2,int m_Capacity 数组容量 3,int m_Size 数组大小 行为: 1,myArray(int capacity) 构造函数 2,myArray(const MyArray&arr) 拷贝构造函数 3,operator= 重载赋值操作符= 4,operator[

  • C++函数模板与类模板相同与不同介绍

    目录 1.模板 1.1何为模板 1.2C++的模板的形式有两种 1.3如何定义一个函数模板 1.4语法形式 1.5模板的编译机制 2.函数模板 2.1调用方式 2.2函数模板的特化与调用优先级 3.可变参函数模板 3.1概念 3.2代码实现(实现一个c中的printf的函数) 4.类模板 4.1类模板的定义形式 4.2代码实例 5.类模板中的特殊属性的初始化方式及继承与多态 5.1代码实例 5.2使用类模板去实现一个数据结构 5.3类模板的特化 5.4C++中类模板中的内嵌类 1.模板 1.1何

  • Java中类的定义和初始化示例详解

    类的定义 类的定义格式 //创建类 class ClassName{ field ://成员属性/字段 method://方法 } class为定义类的关键字,ClassName为类的名字,{ }为类的主体: 例如: class Person{ public String name ; //成员属性 public int age; public void eat(){ // 方法 System.out.println("吃饭!"); } } 类的成员 类的成员包含,字段(成员变量),方

  • 如何使用Serializable接口来自定义PHP中类的序列化

    关于PHP中的对象序列化这件事儿,之前我们在很早前的文章中已经提到过 __sleep() 和 __weakup() 这两个魔术方法.今天我们介绍的则是另外一个可以控制序列化内容的方式,那就是使用 Serializable 接口.它的使用和上述两个魔术方法很类似,但又稍有不同. Serializable接口 class A implements Serializable { private $data; public function __construct(){ echo '__construc

  • 概述java虚拟机中类的加载器及类加载过程

    1. 类加载子系统 1.1 概述 类加载子系统负责从文件系统或者网络中加载Class文件,Class文件在文件开头有特定的文件标识 ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine 决定 加载的类信息存放于一块成为 :方法区的内存空间,除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射) 字节码中的常量池加载到 方法区 -----> 运行时常量池信息 1

  • Java中类与对象的相关知识点总结

    目录 一.面向过程与面向对象的理解 二.类与对象的理解与认识 三.类的成员 1.字段/属性/成员变量 2.对null的基本认识 3.方法 (method) 4.static 关键字 四.封装 1. private实现封装 2.getter和setter方法 五.构造方法 1.构造方法的基本语法及使用 2.this关键字 六.Java中的代码块 1.认识代码块 2.普通代码块 3.构造代码块 4.静态代码块 七.toString方法 1.重写println的toString方法 2.匿名对象 八.

  • 浅析C++函数模板和类模板

    目录 一.函数模板 1.函数模板的定义和使用 2.函数模板的编译原理 3.函数模板的声明 二.类模板 1.类模板的定义和使用 2.类模板的编译原理 3.类模板的继承和派生 C++语言全盘继承了C语言的标准库,其中包换非常丰富的系统函数,例如输入/输出函数.数学函数.字符串处理函数和动态内存分配函数等.C++语言另外又增加了一些新的库,我们把C++语言新增的这部分库称为C++标准库.C++语言的模板技术包括函数模板和类模板.模板技术是一种代码重用技术,函数和类是C++语言中两种主要的重用代码形式.

随机推荐