分析:容器类中要存放数组,而且数组类型不确定,所以应采用泛型编程,容器类要用到下标[]、赋值=、以及输出<<,所以应对这几个操作符进行重载。
第一步:模板类的框架搭建
#pragma once #include <iostream> using namespace std; template<typename T> class myvector { //重载左移运算符,输出类对象时等同于输出容器中的每个元素,注意模板类中的友元函数要加<T> friend ostream& operator<<<T>(ostream& out, myvector<T>& obj); public: //无参构造 myvector(); //有参构造 myvector(int size); //拷贝构造 myvector(const myvector& obj); //析构函数 ~myvector(); //重载[] T& operator[](int index); //重载= myvector<T>& operator=(const myvector<T>& obj); private: //容器的空间 T *p; //容器的容量 int len; };
第二步:模板类的模板函数编写
#include "myvector.h" template<typename T> ostream& operator<<(ostream& out, myvector<T>& obj) { for (int i = 0; i <obj.len; i++) { out << obj.p[i] << " "; } out << endl; return out; } //无参构造 template<typename T> myvector<T>::myvector() { this->len = 1; p = new T[len]; } //有参构造 template<typename T> myvector<T>::myvector(int size) { this->len = size; p = new T[len]; } //拷贝构造 myvector<int> t2(t1); template<typename T> myvector<T>::myvector(const myvector<T>& obj) { this->len = obj.size; p = new T[len]; } //析构函数 template<typename T> myvector<T>::~myvector() { if (p != NULL) { delete[] p; p = NULL; len = 0; } } //重载[]运算符 t1[5] template<typename T> T& myvector<T>::operator[](int index) { return p[index]; } //重载=运算符 t2=t1(把t1赋给t2),返回的是当前对象 template<typename T> myvector<T>& myvector<T>::operator=(const myvector<T>& obj) { //第一步:清除内存 if (p!=NULL) { delete[] p; p = NULL; len = 0; } //第二步:将obj 的属性赋值给左值对象 len = obj.len; p = new T[len]; //第三步:添加元素 for (int i = 0; i < len; i++) { p[i] = obj.p[i]; } return *this; }
第三步:老师类的编写
#pragma once #include <iostream> using namespace std; class Teacher { friend ostream& operator<<(ostream& out, Teacher& obj); public: //无参构造 Teacher(); //有参构造 Teacher(char *name,int age); //重载拷贝构造(本类中含有指针属性,需要对拷贝构造进行重载以防止浅拷贝) Teacher(const Teacher& obj); //重载=运算符(本类中含有指针属性,需要对=运算符进行重载以防止浅拷贝) Teacher& operator=(const Teacher& obj); //析构 ~Teacher(); private: char* p_name; int age; };
#include "Teacher.h" ostream& operator<<(ostream& out, Teacher& obj) { out << obj.p_name << ", " << obj.age << endl; return out; } //无参构造 Teacher::Teacher() { p_name = new char[1]; strcpy_s(p_name,1, ""); age = 20; } //有参构造 Teacher::Teacher(char *name, int age) { p_name = new char[strlen(name) + 1]; strcpy_s(p_name, strlen(name)+1,name); this->age = age; } //重载拷贝构造(本类中含有指针属性,需要对拷贝构造进行重载以防止浅拷贝) Teacher::Teacher(const Teacher& obj) { p_name = new char[strlen(obj.p_name) + 1];//开辟比obj的p_name长度大1 的char空间 strcpy_s(p_name, strlen(obj.p_name) + 1,obj.p_name );//将名称拷贝,p_name与obj.p_name是两块独立的存储空间 this->age = obj.age; } //重载=运算符(本类中含有指针属性,需要对=运算符进行重载以防止浅拷贝) Teacher& Teacher::operator=(const Teacher& obj) { //第一步:清除之前的内存 if (p_name != NULL) { delete[] p_name; p_name = NULL; age = 20; } //第二步:拷贝数据 p_name = obj.p_name; age = obj.age; //第三步:返回左值 return *this; } //析构 Teacher::~Teacher() { if (p_name != NULL) { delete[] p_name; p_name = NULL; age = 20; } }
第四步:测试程序
#include <iostream>
#include "myvector.h"
#include "myvector.cpp"
#include "Teacher.h"
using namespace std;
#include "myvector.h"
#include "myvector.cpp"
#include "Teacher.h"
using namespace std;
int main()
{
//简单类型
myvector<int> t1(10);
for (int i = 0; i < 10; i++)
{
t1[i] = i;
}
cout << t1 << endl;
myvector<int> t2(10);
t2 = t1;//赋值操作
cout << t2 << endl;
{
t1[i] = i;
}
cout << t1 << endl;
myvector<int> t2(10);
t2 = t1;//赋值操作
cout << t2 << endl;
//简单类型
myvector<char> t3(3);
for (int j = 97; j < 100;j++)
{
t3[j-97] = j;
}
cout << t3 << endl;
//复合类型
Teacher obj1("张三",20), obj2("李四",30), obj3("王二",40), obj4("宋五",50);
myvector<Teacher> t4(4);
t4[0] = obj1;//装值过程是一个拷贝过程,即t4[0]装的是obj1的副本,由于对Teacher类进行的重载,所以不会发生浅拷贝
t4[1] = obj2;
t4[2] = obj3;
t4[3] = obj4;
cout << t4 << endl;//输出t4实质上是输出Teacher类的每个对象,由于Teacher类对<<运算符进行了重载,所以顺利输出
return 0;
}
第四步:测试结果