【泛型编程】类模板实现简单的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;
}
在向容器中装入自己定义的类对象时,一定要自己实现拷贝构造函数,否则可能出现浅拷贝的问题。