今天在重新学习了数据结构中的顺序存储结构-顺序表之后,尝试跟随视频完成了基于c语言的动态数组实现,发现由于c语言中没有模板这一概念,所以它的实现主要针对单一的内置数据类型如int等来展开。在学习的时候,就萌生了使用c++类模板来实现动态数组的想法。感觉整体敲的时候思路还是比较清晰的,但是也出现了语句顺序,delete[]和new[]不匹配的问题,以及在实现自定义数据类型操作时需要运算符重载上有点迷糊(把问题想复杂了,只需要重载元素数据类型的运算符即可。)代码经过检查,没有内存泄漏。

       类模板的成员函数的创建时机在调用时,分文件编写时链接不到,所以一般通过包含.cpp或者.hpp(声明和定义放一起)的方式来给出。

       这套代码直接在模板类中提供了多个接口,用到了类和类模板的分文件编写,感觉改BUG和验证的时间比写的时间多。虽然用了半天时间才写好,感觉对我很有意义。

Dynamic_Array_Cpp.hpp                              

#include<iostream>
#include"Person.h"

using namespace std;

#pragma once
template<typename ElementType>
class Dynamic_Array_Cpp
{
public:
	Dynamic_Array_Cpp();

	void Push_Back_Array(ElementType value);

	void RemoveByPos_Array(int pos);

	void RemoveByValue_Array(ElementType value);

	int Find_Array(ElementType value);

	void Print_Array();

	void Clear_Array();

	int Capacity_Array();

	int Size_Array();

	ElementType& At_Array(int pos);

	bool operator==(ElementType Value);

	~Dynamic_Array_Cpp();

	ElementType* m_Parry;
	int m_Capacity;
	int m_Size;
};

//template<typename ElementType>
//ostream& operator<<(ostream& cout,  Dynamic_Array_Cpp<ElementType>& val)
//{
//	for (int i = 0; i < val.m_Size; i++)
//	{
//		cout << val.m_Parry[i] << " ";
//	}
//}

template<typename ElementType>
Dynamic_Array_Cpp<ElementType>::Dynamic_Array_Cpp()
{
	this->m_Capacity = 20;
	this->m_Parry = new ElementType[this->m_Capacity];

}

template<typename ElementType>
Dynamic_Array_Cpp<ElementType>::~Dynamic_Array_Cpp()
{
	if (this->m_Parry != NULL)
	{
		delete[] this->m_Parry;
		this->m_Parry = NULL;
	}
}

template<typename ElementType>
void Dynamic_Array_Cpp<ElementType>::Push_Back_Array(ElementType value)
{
	if (this == NULL || this->m_Parry == NULL)
	{
		return;
	}

	if (this->m_Capacity == this->m_Size)
	{
		ElementType* newspace = new ElementType [this->m_Capacity+this->m_Capacity];
        
		for (int i = 0; i < this->m_Size; i++)
		{
			newspace[i] = this->m_Parry[i];
		} 

		delete[] this->m_Parry;
		this->m_Parry = newspace;
		this->m_Capacity = this->m_Capacity*2;
	}

	this->m_Parry[this->m_Size] = value;
	this->m_Size++;
}

template<typename ElementType>
void Dynamic_Array_Cpp<ElementType>::RemoveByPos_Array(int pos)
{
	if (this == NULL || this->m_Parry == NULL)
	{
		return;
	}
	
	if (pos< 0 || pos>this->m_Size)
	{
		return;
	}
    
	for (int i = pos; i < this->m_Size; i++)
	{
		this->m_Parry[i] = this->m_Parry[i + 1];
	}
    
	this->m_Size--;
}

template<typename ElementType>
void Dynamic_Array_Cpp<ElementType>::RemoveByValue_Array(ElementType value)
{
	if (this == NULL || this->m_Parry == NULL)
	{
		return;
	}
    
	int pos = this->Find_Array(value);
	this->RemoveByPos_Array(pos);
}

template<typename ElementType>
int Dynamic_Array_Cpp<ElementType>::Find_Array(ElementType value)
{
	if (this == NULL || this->m_Parry == NULL)
	{
		return -1;
	}
    
	int pos = -1;

	for (int i = 0; i < this->m_Size; i++)
	{
		if (this->m_Parry[i] == value)
		{
			pos = i;
		}
	}

	return pos;
}

template<typename ElementType>
void Dynamic_Array_Cpp<ElementType>::Print_Array()
{
	
	if (this == NULL || this->m_Parry == NULL)
	{
		return;
	}

	for (int i = 0; i < this->m_Size; i++)
	{
		cout << this->m_Parry[i]<<" ";
	}
	cout << endl;
}

template<typename ElementType>
void Dynamic_Array_Cpp<ElementType>::Clear_Array()
{
	if (this == NULL || this->m_Parry == NULL)
	{
		return;
	}

	this->m_Size = 0;
}

template<typename ElementType>
int Dynamic_Array_Cpp<ElementType>::Capacity_Array()
{
	if (this == NULL || this->m_Parry == NULL)
	{
		return -1;
	}

	return this->m_Capacity;
}

template<typename ElementType>
int Dynamic_Array_Cpp<ElementType>::Size_Array()
{
	if (this == NULL || this->m_Parry == NULL)
	{
		return -1;
	}

	return this->m_Capacity;
}

template<typename ElementType>
ElementType& Dynamic_Array_Cpp<ElementType>::At_Array(int pos)
{
	return this->m_Parry[pos];
}

Person.cpp

#include"Person.h"
using namespace std;
Person::Person(string name, int age) :m_Name(name), m_Age(age) {}
Person::Person() {}
bool Person::operator==(const Person& p)
{
	return this->m_Name == p.m_Name && this->m_Age == p.m_Age;
}

ostream& operator<<(ostream& cout, Person& p)
{
	cout <<"姓名为: " << p.m_Name << " 年龄为: " << p.m_Age << endl;
	return cout;
}

 Person.h

#pragma once
#include<iostream>
using namespace std;
class Person
{
	friend ostream& operator<<(ostream& cout, Person& p);

public:
	Person();
	Person(string name, int age);
	bool operator==(const Person& p);

	string m_Name;
	int m_Age;
};

 动态数组cpp实现.cpp

#include"Dynamic_Array_cpp.hpp"
#include "Person.h"
#include<vld.h>

void test01()
{
	//生成动态数组对象指针,堆区开辟数据
	Dynamic_Array_Cpp<int>* myArray = new Dynamic_Array_Cpp<int>;
    
	//扩容测试
	cout << "容量为: " << myArray->m_Capacity << endl;
	cout << "大小为: " << myArray->m_Size << endl;
	for (int i = 0; i < 30; i++)
	{
		myArray->Push_Back_Array(i);
	}

	cout << "容量为: " << myArray->m_Capacity << endl;
	cout << "大小为: " << myArray->m_Size << endl;
	myArray->Print_Array();
   
	//元素删除测试
	myArray->RemoveByPos_Array(4);
	myArray->RemoveByValue_Array(3);
    
	//打印元素
	myArray->Print_Array();
    
	//查找测试
	int pos = myArray->Find_Array(25);
	cout <<"位置为: "<<pos<<"值为: "<<myArray->At_Array(pos) << endl;

	//清空测试
	myArray->Clear_Array();
	myArray->Print_Array();

	//销毁堆区的动态数组
	delete myArray;
}

void test02()
{
	//创建Person类元素
	Person p1("张三", 18);
	Person p2("李四", 19);
	Person p3("王五", 20);
	Person p4("赵六", 15);
	Person p5("陈七", 23);

	//尾插插入数据
	Dynamic_Array_Cpp<Person>* myArray = new Dynamic_Array_Cpp<Person>;
	myArray->Push_Back_Array(p1);
	myArray->Push_Back_Array(p2);
	myArray->Push_Back_Array(p3);
	myArray->Push_Back_Array(p4);
	myArray->Push_Back_Array(p5);

	//打印元素
	myArray->Print_Array();
	cout << "容量为: " << myArray->m_Capacity << endl;
	cout << "大小为: " << myArray->m_Size << endl;

	//删除测试
	myArray->RemoveByPos_Array(1);
	myArray->RemoveByValue_Array(p1);
	
	//打印元素
	myArray->Print_Array();
	cout << "容量为: " << myArray->m_Capacity << endl;
	cout << "大小为: " << myArray->m_Size << endl;
    
	Person pp("赵六", 15);
	int pos = myArray->Find_Array(pp); 
	cout << "pos =" << pos << endl;
	cout<< myArray->At_Array(pos) << endl;

	//清空测试
	myArray->Clear_Array();
	myArray->Print_Array();

	//销毁堆区的动态数组
	delete myArray;
}


int main()
{
	//test01();
	test02();

	system("pause");
	return 0;
}

 测试结果 test01()

 test02() 没对齐是打印时的空格造成的

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐