首页 > 其他分享 >通过模板类实现一个简单的vector容器

通过模板类实现一个简单的vector容器

时间:2024-01-05 16:04:01浏览次数:33  
标签:容器 arr capacity 实例 vector template 模板 size

什么是模板

模板分为类模板和函数模板,关键字为template,基本的声明形式如下:

template<class T>;
//也可以写成这样
template<typename T>

class 和 typename 在声明模板参数时的用法是相似的,一般情况下可以互换

但在成员模板内部访问嵌套类型时,需要使用 typename。

下面举一个例子加以理解:

template <class T>
class MyClass {
public:
    typename T::SomeType member; 
    // 使用typename来指明T::SomeType是一个类型
};

模板的原理

模板的原理就是通过所传递的参数类型进行实例化,推导出参数的具体类型,实例化分为显式实例化和隐式实例化。

隐式实例化

当我们不指定参数的类型时,编译器会根据所传递的参数类型进行隐式的实例化,并推导出参数的具体类型。

#include <iostream>

template<class T>
void swap(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}
int main(void) {
	int a = 10;
	int b = 20;
	swap(a, b);
	std::cout << "a = " << a << ' ' << "b = " << b << std::endl;
	swap(a, b);
	std::cout << "a = " << a << ' ' << "b = " << b << std::endl;

	return 0;
}

这里我们并没有显式的指定参数的类型,所以编译器根据传递的参数自动进行了隐式实例化,并推导出了参数的具体类型。

然而,当我们传递的参数类型不统一时,编译器就无法进行隐式实例化,会导致程序报错。

#include <iostream>

template<class T>
void swap(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}
int main(void) {
	int a = 10;
	double b = 20.1;
	swap(a, b); //double和int类型不统一,隐式实例化失败
	std::cout << "a = " << a << ' ' << "b = " << b << std::endl;
	swap(a, b);
	std::cout << "a = " << a << ' ' << "b = " << b << std::endl;

	return 0;
}

显式实例化

所以,针对以上的情况,我们可以显式的声明参数类型,告诉编译器进行显式的实例化,从而无需对参数类型进行推导。

#include <iostream>

template<class T>
T Add(const T& a, const T& b) {
	return a + b;
}
int main(void) {
	int a = 10;
	double b = 10.2;
	std::cout << Add<int>(a, b) << std::endl; 
  //对Add函数进行了显式的实例化,将参数类型显式的定义为int
	//此时结果为20
	return 0;
}

模板有两种类型,分别是函数模板和类模板,下面分别加以介绍:

函数模板

函数模板较为简单,首先声明模板关键字template,随后实现函数的定义,当我们传入实参时,模板会根据参数类型进行实例化,从而实现模板函数功能。

template<class T>
void swap(T& a, T& b) { //引用传参
	T temp = a;
	a = b;
	b = temp;
}


类模板

类似于函数模板,只不过这里时声明成员参数为模板类型,

下面我将实现一个简单的vector容器加以说明:

这里的vector是一个动态容器,所以要对容器进行动态扩容

#include <iostream>

template<class T>
class vector {
public:
	vector(){ //构造函数初始化
		arr = nullptr;
		_size = 0;
		_capacity = 0;
	}
	~vector() { //析构函数,对容器进行释放操作
		delete []arr;
		arr = nullptr;
	}

	void push_back(const T& target) {
		if (_size == _capacity) { 
      // 判断,并进行扩容
			size_t n_capacity = _capacity == 0 ? 2 : _capacity * 2;
			T* temp = new T[n_capacity]; //在堆上重新分配内存
			if (arr) {
				memcpy(temp, arr, sizeof(T) * _size); //拷贝原数据
				delete[]arr;
        arr = nullptr; 
        //可以省略,下面的代码重置了arr的指向,所以不会出现悬空指针
			}
			arr = temp;
			_capacity = n_capacity;
		}
		arr[_size++] = target;
	}
	T operator[](size_t i) {
		return arr[i];
	}
private:
	T* arr;
	size_t _size;
	size_t _capacity;
};
int main(void) {
	vector<int> vec;
	vec.push_back(1);
	std::cout << vec[0] << std::endl;
	return 0;
}

标签:容器,arr,capacity,实例,vector,template,模板,size
From: https://blog.51cto.com/u_16271511/9115026

相关文章

  • 以Docker容器的形式运行GVM-11
    以Docker容器的形式运行GVM-11OpenVAS(OpenVulnerabilityAssessmentSystem)是在nessus基础上发展起来的一个开源的漏洞扫描程序,其核心部件是一套漏洞测试程序,可以检测远程系统和应用程序中的安全问题。 (一)在ubuntu18系统中安装dockeraptinstalldocker.io //在线安装dockersy......
  • 11、盛水最多的容器
    法一:暴力解法(超时)intmaxArea(vector<int>&height){intmax=0;for(inti=0;i<height.size();i++){for(intj=i+1;j<height.size();j++){intminHeight=min(height[i],height[j]);intcapacity=(j-i......
  • Kubernetes容器运维与编排技术的精髓
    Kubernetes容器运维与编排技术的精髓在当今云原生技术的浪潮中,Kubernetes(简称K8s)无疑是最为引人注目的容器编排工具之一。作为一个强大而灵活的平台,Kubernetes在容器化应用的自动部署、扩展、管理方面展现了其卓越的能力。本篇博文将深度剖析Kubernetes容器运维与编排技术,重点关注......
  • C++函数模板详解,轻松实现通用函数
    C++函数模板详解,轻松实现通用函数函数模板编写通用函数您也可以为独立的函数编写模板。其语法与类模板类似。例如,您可以编写以下通用函数来在数组中查找一个值并返回其索引:staticconstsize_tNOT_FOUND{static_cast<size_t>(-1)};template<typenameT>size_tFind(const......
  • Docker容器
    Docker容器产生的日志文件可以被清理。由于Docker容器的日志默认存储在宿主机的磁盘上,随着容器运行时间的增长,这些日志文件可能会占用大量磁盘空间,因此定期清理是非常必要的。清理Docker容器日志的方法如下:查看容器日志路径:首先,确定需要清理日志的容器ID或名称,然后找到其日志文件......
  • 力扣11-盛最多水的容器
    难度:【中等】题目给画了图,比较方便理解。第一个思路是把所有的面积都计算一遍,显然时间复杂度很高;接着思考第二个方法,使用双指针,通过移动首尾指针来计算面积:如果下一个height超过当前值,就移动该指针,直到两个指针相遇。写完代码运行超时。超时是因为死循环了,因为上面的移动指针的......
  • Spring MVC 源码分析 - WebApplicationContext 容器的初始化
    随着 SpringBoot 和 SpringCloud 在许多中大型企业中被普及,可能你已经忘记当年经典的Servlet+SpringMVC的组合,是否还记得那个 web.xml 配置文件。在开始本文之前,请先抛开 SpringBoot 到一旁,回到从前,一起来看看Servlet是怎么和SpringMVC集成,怎么来初始化Sprin......
  • 【C++】STL 容器 - set 集合容器 ⑥ ( pair 对组简介 | pair 对组元素访问 | set 集合
    文章目录一、pair对组1、pair对组简介2、pair对组元素访问3、代码示例-pair对组4、set集合容器存储pair对组元素二、set集合容器insert插入结果类型-pair对组1、std::set#insert函数原型分析2、代码示例-std::set#insert函数插入元素结果分析一、pair对组1......
  • 【C++】STL 容器 - set 集合容器 ⑤ ( 仿函数 functor 简介 | 仿函数 functor 调用 |
    文章目录一、仿函数functor1、仿函数functor简介2、仿函数functor调用3、代码示例-仿函数functor调用二、为自定义类元素设置排序规则-仿函数functor1、自定义类排序规则2、仿函数-实现自定义类排序规则3、重载<运算符函数-实现自定义类排序规则一、仿函数fu......
  • 【C++】STL 容器 - set 集合容器 ④ ( 设置 set 集合容器的排序规则 | 默认的 set 集
    文章目录一、设置set集合容器的排序规则1、默认的set集合容器-从小到大排列2、设置set集合容器从大到小排列二、使用仿函数自定义set集合容器排序规则1、仿函数概念2、使用仿函数实现set集合容器排序规则一、设置set集合容器的排序规则1、默认的set集合容器-......