【C++手写Vector模板类】构造与模板初试

一.输出效果

在这里插入图片描述

测试文件:

main.cpp

#include "Vector.hpp"
#include <vld.h>

int main() {
	cout << "1.存储类类型数据" << endl;
	Vector<Beauty*> btV(2);//若Vector<Beauty> btV(2);btV[0] = la;拷贝全部耗费空间太大;Vector类内会根据Beauty大小
						   //仅分配了Beauty*的内存,故指针还要另外分配对象内存
	//Beauty la(22, "Larry");
	//Beauty je(20, "Jessica");
	btV[0] = new Beauty(22, "Larry");//可同时初始化,避免创造新la和je浪费内存
	//btV[0] = &la;//*btv[0]=la;×放地址就行
	btV[1] = new Beauty(20, "Jessica");
	//btV[1] = &je;
	for (int i = 0; i < btV.getCnt(); i++) {
		cout << *btV[i];
	}cout << endl;
	delete btV[0];
	delete btV[1];

	cout << "2.存储int类型数据" << endl;
	//对默认构造函数存储元素赋值为1-5
	Vector<int> intV(5);//integar vector
	for (int i = 0; i < intV.getCnt(); i++) {
		intV[i] = i + 1;
	}

	//打印数组元素
	cout << intV;
	
	cout << "3.存储float类型数据" << endl;
	Vector<float> floatV(5);//integar vector
	for (int i = 0; i < floatV.getCnt(); i++) {
		floatV[i] = (i + 1) * 0.1f;
	}
	cout << floatV;

	//拷贝类
	cout << "4.拷贝类" << endl;
	Vector<int> intV1(intV);
	cout << intV1;

	//赋值类
	cout << "5.赋值类" << endl;
	Vector<int> intV2(2);
	intV2 = intV;
	cout << intV2;

	return 0;
}

二.设计思路

设计类图:

设计思路: 数组模板类( Vector ),完成对int、char、float、double 以及任意的自定义类等类型元素进行管理.cnt标识元素个数, p标识元素首地址. 具以下方法:

a.默认+带参构造函数, 确定存储元素个数
b.拷贝构造函数, 针对动态分配元素, delete与new
c.<<重载: 直接打印数组全部元素 cout << myVector
d.[]重载: 直接访问存储元素 myVector[i] = m_base[i] = *(m_base+i) = 存储及打印元素值
e.赋值构造函数, 整个对象各元素依次赋值
f.获取存有对象存储元素个数 cnt

#pragma once
#include <iostream>
#include "Beauty.h"
using namespace std;

//记得有指针就要分配内存->依据存入元素个数,分配动态内存
//什么类型的指针,相应存的元素也就是什么类型的->无需考虑这个元素所占字节长度
template <typename T>
class Vector
{
public:
	Vector(int cnt = 128);//构造函数(除赋值构造函数)的函数名后不需加<T>
	~Vector();
	Vector(Vector& src);

	Vector& operator=(Vector& src);

	T& operator[](int i);

	int getCnt();

private:
	int cnt;//member_count存储元素个数
	T* p;//member_pointer存储元素首地址

	friend ostream& operator<< <T>(ostream& os, const Vector<T>& object);
};

模板类实现文件, 因具有头文件的多文件适用性, 又具cpp文件的实现函数功能, 故命名为hpp文件, 因h在前, 故编译时要include包含.h文件

Vector.hpp

#include "Vector.h"

template<typename T>
inline Vector<T>::Vector(int cnt) {
	this->cnt = cnt > 0 ? cnt : 128;
	p = new T[this->cnt];
}

template<typename T>
inline Vector<T>::~Vector()
{
	delete[] p;
	p = nullptr;
}

template<typename T>
inline T& Vector<T>::operator[](int i)
{
	if (i >= 0) {
		return p[i];
	}
	else {
		cout << "数组长度有误!" << endl;
		exit(1);
	}
}

template<typename T>
inline unsigned Vector<T>::getCnt()
{
	return cnt;
}

template<typename T>
inline Vector<T>::Vector(Vector& src)
{
	p = new T[src.cnt];
	cnt = src.cnt;
	for (int i = 0; i < src.cnt; i++) {
		p[i] = src[i];//this[i]好像不行??
	}
}

template<typename T>
inline Vector<T>& Vector<T>::operator=(Vector& src)
{
	if (p) {
		delete[] p;
	}
	p = new T[src.cnt];
	cnt = src.cnt;
	for (int i = 0; i < src.cnt; i++) {
		(*this)[i] = src[i];
	}
	return *this;
}

template<typename T>
ostream& operator<<(ostream& os, const Vector<T>& object)
{
	for (int i = 0; i < object.cnt; i++) {
		os << object.p[i] << "\t";//若存储值,可直接打印;若存储对象,无法直接打印->可直接创建os<<Beauty.name<<" age
	}os << endl;

	return os;
}

辅助测试的类文件:

Beauty.h

#pragma once
#include <iostream>
using namespace std;
/*
附1:优化Student类, 属性变成 char *pname, 构造函数里面 分配内存
附2:优化Student类,析构函数 释放pname指向的内存空间
附3:优化Student类,避免浅赋值/浅拷贝 重载= 和 重写拷贝构造函数
附4:思考 Student * 类成员如何操作
*/
class Beauty
{ 
public:
	Beauty(int age = 0, const char* name = "");
	~Beauty();//数据成员有指针就必须写析构函数
	Beauty(const Beauty& src);//数据成员有指针就必须写拷贝构造函数
	Beauty& operator=(const Beauty& src);//数据成员有指针就必须写赋值构造函数

	friend ostream& operator<<(ostream& os, const Beauty& beauty);

private:
	int age;
	char* name;
};

ostream& operator<<(ostream& os, const Beauty& beauty);

Beauty.cpp

#include "Beauty.h"

ostream& operator<<(ostream& os, const Beauty& beauty)
{
	os << "美女的姓名为:" << beauty.name 
	   << ",年龄为:" << beauty.age << endl;
	return os;
}

Beauty::Beauty(int age, const char* name) :age(age)
{//指针的浅拷贝和深拷贝才有差别->浅拷贝指向同一块内存,深拷贝指向不同内存
 //此次数据成员若不含指针,故无需再手动定义深拷贝

	/*int len = name.length() + 1;
	this->name = new char[len];
	strcpy_s(this->name, len, name.c_str());*/

	int len = strlen(name) + 1;
	this->name = new char[len];
	strcpy_s(this->name, len, name);
}

Beauty::~Beauty()
{
	if (name) {
		delete[] name;
	}
}

Beauty::Beauty(const Beauty& src)
{
	int len = strlen(src.name) + 1;
	this->name = new char[len];
	strcpy_s(this->name, len, src.name);

	age = src.age;
}

Beauty& Beauty::operator=(const Beauty& src)
{
	if (name) {
		delete[] name;
	}
	int len = strlen(src.name) + 1;
	this->name = new char[len];
	strcpy_s(this->name, len, src.name);

	age = src.age;

	return *this;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值