【泛型编程】类模板实现简单的vector容器

首先创建一个类的.h和.cpp文件,分别如下

 UserVector.h文件

#pragma once //只包含一次

#include <iostream>
using namespace std;

template<typename user_t>
class UserVector
{
public:
	//构造函数与析构函数
	UserVector(int len = 0); //有了默认初始参数,不需要在写无参构造函数 UserVector();
	UserVector(UserVector<user_t>& v); //UserVector<user_t> 必须指明类型来告诉编译器如何分配内存
	~UserVector();
public:
	//重载函数
	user_t& operator[](int index);
	friend ostream& operator<< <user_t> (ostream& out, UserVector<user_t>& u);
	UserVector<user_t>& operator=(UserVector<user_t>& u);
private:
	int		len;
	user_t* p;
};

其中

#pragma once 

表示只包含一次该头文件,防止重复包含导致的重定义,相当于C语言中的

#ifndef _USER_VECTOR_H
#define _USER_VECTOR_H

/*
程序代码
*/

#endif

UserVector.cpp文件

#include "UserVector.h"

template<typename user_t>
UserVector<user_t>::UserVector(int len)
{
	this->len = len;
	this->p = new user_t[this->len];
}

template<typename user_t>
UserVector<user_t>::UserVector(UserVector<user_t>& v)
{
	this->len = v.len;
	this->p = new user_t[this->len];
	for (int i = 0; i < this->len; i++)
	{
		this->p[i] = v.p[i];
	}
}

template<typename user_t>
UserVector<user_t>::~UserVector()
{
	if (this->p != NULL)
	{
		delete[] this->p;
	}
	this->p = NULL;
	this->len = 0;
}

template<typename user_t>
user_t& UserVector<user_t>::operator[](int index)
{
	return this->p[index];
}

template<typename user_t>
//std::ostream& operator<< <user_t> (std::ostream& out, UserVector<user_t>& u)
//错误	C2768	“operator << ”: 非法使用显式模板参数	
std::ostream& operator<<(std::ostream& out, UserVector<user_t>& u)
{
	for (int i = 0; i < u.len; i++)
	{
		out << u.p[i] << " ";
	}
	return out;
}

template<typename user_t>
UserVector<user_t>& UserVector<user_t>::operator=(UserVector<user_t>& u)
{
	if (this->p != NULL)
	{
		delete[] this->p;
		//无需置NULL,因为下面立马要修改
	}

	this->len = u.len;
	this->p = new user_t[this->len];

	for (int i = 0; i < this->len; i++)
	{
		this->p[i] = u.p[i];
	}

	return *this;
}

这里注意,在类模板中重载运算符的时候一定不能乱用友元函数,一般只有重载左移右移运算符时,才能使用友元函数,否则会报各种错误,并且在重载左移右移运算符的时候,函数声明一定要这样声明

friend ostream& operator<< <user_t> (ostream& out, UserVector<user_t>& u);

主测试函数函数如下

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
using namespace std;

//#include "UserVector.h" //报一堆错
#include "UserVector.cpp"

void FuncTest1()
{
	//1. int 类型的容器
	UserVector<int> i1(10);
	for (int i = 0; i < 10; i++)
	{
		i1[i] = i;
	}
	cout << "i1: " << i1 << endl;

	UserVector<int> i2 = i1;
	cout << "i2: " << i2 << endl;

	UserVector<int> i3;
	i3 = i2;
	cout << "i3: " << i3 << endl;

	//2. char
	UserVector<char> c1(3);
	c1[0] = 'a';
	c1[1] = 'b';
	c1[2] = 'c';
	cout << "c1: " << c1 << endl;

	UserVector<char> c2;
	c2 = c1;
	cout << "c2: " << c2 << endl;
}

class People
{
public:
	People()
	{
		this->age = 0;
		this->name = NULL;
	}
	People(int age, const char* p) //装入容器时,必须要有拷贝构造函数
	{
		this->age = age;
		this->name = new char[strlen(p) + 1];
		strcpy(this->name, p);
	}
	People(People& p)
	{
		this->age = p.age;
		this->name = new char[strlen(p.name) + 1];
		strcpy(this->name, p.name);
	}
	~People()
	{
		if (this->name != NULL)
		{
			delete[] this->name;
		}
		this->name = NULL;
		this->age = 0;
	}
public:
	People& operator=(People& p)
	{
		if (this->name != NULL)
		{
			delete[] this->name;
		}

		this->name = new char[strlen(p.name) + 1];
		this->age = p.age;
		strcpy(this->name, p.name);

		return *this;
	}
	friend ostream& operator<<(ostream& out, People& p)
	{
		out << p.name << ": " << p.age << endl;
		return out;
	}
private:
	int		age;
	char*	name;
};

void FuncTest2()
{
	People p1(16, "p1"), p2(17, "p2"), p3(18, "p3");
	UserVector<People> V(3);
	V[0] = p1;
	V[1] = p2;
	V[2] = p3;

	cout << V[0] << V[1] << V[2] << endl;
}

int main()
{
	//装入普通类型
	FuncTest1();

	//装入 类对象
	FuncTest2();

	system("pause");
	return 0;
}

在向容器中装入自己定义的类对象时,一定要自己实现拷贝构造函数,否则可能出现浅拷贝的问题。

posted @ 2022-03-13 21:26  Mindtechnist  阅读(14)  评论(0编辑  收藏  举报  来源