数组模板类MyVector

类模板练习:可以管理基本数据类型,类元素,类指针

定义类模板

MyVector.h

#pragma once
#include <iostream>
using namespace std;

//先考虑类型int char
template <typename T>
class MyVector
{
	friend ostream& operator<< <T>(ostream& out, MyVector& obj);
public:
	MyVector(int size = 0);
	MyVector(const MyVector& obj1);
	~MyVector();
	int getLen()
	{
		return m_len;
	}
	//重载[] = <<
	T& operator[](int index);
	MyVector& operator=(MyVector& obj2);

private:
	T *m_space;
	int m_len;
};

实现类模板成员函数

MyVector.cpp

#include <iostream>
#include "MyVector.h"
using namespace std;

template <typename T>
ostream& operator<<(ostream& out, MyVector<T>& obj)
{
	for (int i = 0; i < obj.m_len; i++) {
		out << obj.m_space[i] << " ";
	}
	out << endl;
	return out;
}

template <typename T>
MyVector<T>::MyVector(int size)
{
	m_len = size;
	m_space = new T[m_len];
}

template <typename T>
MyVector<T>::MyVector(const MyVector<T>& obj1)	//拷贝构造函数
{
	m_len = obj1.m_len;
	m_space = new T[m_len];
	for (int i = 0; i < m_len; i++) {	//复制内容
		m_space[i] = obj1.m_space[i];
	}
}

template <typename T>
MyVector<T>::~MyVector()
{
	if (m_space != NULL) {
		delete[] m_space;
		m_space = NULL;
		m_len = 0;
	}
}

//重载[] = <<
template <typename T>
T& MyVector<T>::operator[](int index)
{
	return m_space[index];
}

template <typename T>	//a2=a1
MyVector<T>& MyVector<T>::operator=(MyVector<T>& obj2)
{
	if (m_space != NULL) {
		delete[] m_space;
		m_space = NULL;
		m_len = 0;
	}
	m_len = obj2.m_len;
	m_space = new T[m_len];
	for (int i = 0; i < m_len; i++) {	//复制内容
		m_space[i] = obj2.m_space[i];
	}
	return *this;
}

基本数据类型,类元素,类指针 测试框架

MyVectorMain.cpp

//类模板练习:可以管理基本数据类型,类元素,类指针

//这种多文件的调试在改变代码后有时需要重新生成解决方案再进行调试
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "MyVector.cpp"
using namespace std;

/*//定义一个Teacher类,其对象放入类模板里
class Teacher
{
public:
	Teacher()
	{
		age = 20;
		strcpy(name, "");
	}
	Teacher(int age, const char *name)	//出错后这里加const
	{
		this->age = age;
		strcpy(this->name, name);
	}
	void printT()
	{
		cout << name << ", " << age << endl;
	}

private:
	int age;
	char name[32];	//预先分配了内存,不会有浅拷贝的问题
};*/

//优化Teacher类	5个点,拷贝构造 析构 重载= <<
class Teacher
{
	friend ostream& operator<<(ostream& out, Teacher& obj);
public:
	Teacher()
	{
		age = 0;
		pname = NULL;
	}
	Teacher(int age, const char *name)	//还是要加const
	{
		this->age = age;
		if (name != NULL) {
			int len = strlen(name);
			pname = new char[len + 1];
			strcpy(pname, name);
		}
	}
	Teacher(const Teacher& obj)		//拷贝构造函数
	{
		//if (pname != NULL) {	//清除旧内存
		//	delete[] pname;
		//	pname = NULL;
		//	age = 0;
		//}
		age = obj.age;
		if (obj.pname != NULL) {
			int len = strlen(obj.pname);
			pname = new char[len + 1];
			strcpy(pname, obj.pname);
		}
	}
	~Teacher()
	{
		if (pname != NULL) {
			delete[] pname;
			pname = NULL;
			age = 0;
		}
	}
	void printT()
	{
		cout << pname << ", " << age << endl;
	}
	Teacher& operator=(Teacher& obj)	//函数体和拷贝构造函数几乎一样对吗?
	{
		if (pname != NULL) {	//清除旧内存
			delete[] pname;
			pname = NULL;
			age = 0;
		}
		age = obj.age;
		if (obj.pname != NULL) {
			int len = strlen(obj.pname);
			pname = new char[len + 1];
			strcpy(pname, obj.pname);
		}
		return *this;
	}

private:
	int age;
	//采取指针的定义,需解决浅拷贝的问题
	char *pname;
};

ostream& operator<<(ostream& out, Teacher& obj)
{
	out << obj.pname << ", " << obj.age << endl;
	return out;
}

int main02()
{		//无法将参数 2 从“const char [3]”转换为“char *”
	Teacher t1(25, "t1"), t2(26, "t2"), t3(27, "t3"), t4(28, "t4");
	MyVector<Teacher> tarray(5);
	tarray[0] = t1;
	tarray[1] = t2;
	tarray[2] = t3;
	tarray[3] = t4;

	tarray[4] = tarray[0];	//测试Teacher中重载的=

	cout << tarray;		//重载的<<,Teacher对象数组在数组类模板中输出成功!!

	/*for (int i = 0; i < 4; i++) {
		Teacher tmp = tarray[i];
		tmp.printT();
	}*/
	return 0;
}

//以上数据类型为Teacher元素,下面采用Teacher指针
int main()
{		
	Teacher t1(25, "t1"), t2(26, "t2"), t3(27, "t3"), t4(28, "t4");
	MyVector<Teacher *> tarray(5);
	tarray[0] = &t1;
	tarray[1] = &t2;
	tarray[2] = &t3;
	tarray[3] = &t4;

	tarray[4] = tarray[0];

	//cout << tarray;		//此时输出的是地址!应该再重载<<?

	for (int i = 0; i < 5; i++) {	//输出指针类型时采用for循环
		Teacher *tmp = tarray[i];
		tmp->printT();
	}
	return 0;
}

int main01()
{
	MyVector<int> myv1(10);
	for (int i = 0; i < myv1.getLen(); i++) {
		myv1[i] = i + 1;
		cout << myv1[i] << " ";
	}
	cout << endl;
	MyVector<int> myv2 = myv1;
	for (int i = 0; i < myv1.getLen(); i++) {
		cout << myv2[i] << " ";
	}
	cout << endl;
	cout << myv2;

	return 0;
}

结论1: 如果把Teacher放入到MyVector数组中,并且Teacher类的属性含有指针,就是出现深拷贝和浅拷贝的问题。

结论2:需要Teacher封装的函数有:

  1. 重写拷贝构造函数 
  2. 重载等号操作符 
  3. 重载左移操作符。

理论提高:所有容器提供的都是值(value)语意,而非引用(reference)语意。容器执行插入元素的操作时,内部实施拷贝动作。所以STL容器内存储的元素必须能够被拷贝(必须提供拷贝构造函数)。

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值