前言: 文章 对象的添加与删除(一) 只是简单的操作练习。那么这篇文章就带大家一起深入探讨动态内存分配、构造函数 和 析构函数的应用。
一、要求与说明
1、创建一个Person类,属性包括姓名和年龄,并重载运算符输出Person对象。
2、创建一个PersonSet类,用来添加、删除或查找Person对象,要求可以动态开辟和释放存储空间。
3、在main函数中测试实例。本文核心内容都在PersonSet类里。
提示: 以下代码可以直接拷贝至编辑器(有时会遇到版本兼容性问题)。
二、Person类:创建和销毁对象
Person.h 文件
#include<iostream>
using namespace std;
class Person{
private:
char *name; // 姓名
int age; // 年龄
public:
Person(char *_name, int _age); // 构造函数
~Person(); // 析构函数
friend ostream & operator <<(ostream & os ,const Person &p); // 输出运算符重载
};
Person.cpp 文件
#include "Person.h"
#include<iostream>
using namespace std;
Person::Person(char *_name, int _age){
name = new char[strlen(_name)+1];
strcpy(name, _name);
age = _age;
}
Person::~Person(){
if (name != NULL)
{
delete [] name;
name = NULL;
cout<<"Person free ..." <<endl;
}
}
ostream & operator <<(ostream & os ,const Person &p){
os << "name is " << p.name <<endl;
os << " age is " << p.age ;
return os;
}
三、PersonSet类:动态管理Person对象
PersonSet.h
#include "Person.h"
#include<iostream>
using namespace std;
class PersonSet{
private:
Person* *elements; // 指向 存储Person对象的地址 的指针
int capcity; // 总共可以存储多少个Person对象
int size; // 目前已经存储了多少个Person对象
int index; // 迭代容器时,查询到了哪个下标
public:
PersonSet(); // 构造函数
~PersonSet(); // 析构函数
int get_size(); // 获取目前存储了多少个Person对象
void addPerson(Person &p); // 添加Person对象
Person & nextElement(); // 迭代
Person & removeElement(); // 移除最后一个元素,并判断是否释放多余空间
Person & removeElement(int _index); // 重载,移除指定元素,并判断是否释放多余空间
friend ostream & operator << (ostream & os,const PersonSet &ps); //输出运算符重载
};
PersonSet.cpp
#include "PersonSet.h"
PersonSet::PersonSet(){
index = 0;
size = 0;
capcity = 3; // 初始容量设置为3,方便测试
elements = new Person* [capcity]; // 分配一个存储单元
}
PersonSet::~PersonSet(){
if (elements != NULL)
{
delete [] elements;
elements = NULL;
cout<< "Personset free ..." <<endl;
}
}
int PersonSet::get_size(){
return size;
}
void PersonSet::addPerson(Person &p){
// 添加元素前,判断一下剩余空间是否使用完毕
// 空间不足需要先分配一些新的空间,再进行添加操作。
if (size == capcity)
{
cout<<"空间不足,为您开辟一些新的空间"<<endl;
Person* *temp = elements; // 新建一个temp指针,指向elements
elements = new Person*[capcity + 10]; // 给elements重新分配一段新的存储单元
for (int i=0; i<size; i++) // 将temp指向的内存单元依次赋值给elements
elements[i] = temp[i];
elements[size++] = &p; // 添加Person对象
cout<< "第" << size << "个元素添加成功" <<endl;
delete []temp ; // 释放temp,避免内存泄露
temp = NULL;
}
else
{
elements[size++] = &p; // 如果内存充足,直接添加Person对象
cout<< "第" << size << "个元素添加成功" <<endl;
}
}
Person & PersonSet::nextElement(){
if (index >= size)
{
index = 0;
return * elements[index++];
}
return *elements[index++];
}
Person & PersonSet::removeElement(){
Person *temp = elements[size-1]; // 定义一个temp指针, 指向elements的最后一个元素
if (size < capcity/2) // 判断是否可以释放多余空间
{
cout<<"为您释放空间" <<endl;
Person* *str = elements; // 定义一个指针str, 指向elements的第一个存储单元
elements = new Person*[capcity/2]; // 重新为elements分配空间
for (int i=0; i<size; i++) // 重新为elements赋值
elements[i] = str[i];
delete [] str; // 释放str,避免内存泄露
str = NULL;
}
size --;
return *temp; // 返回被删除元素的存储单元
}
Person & PersonSet::removeElement(int _index){
Person* temp = elements[_index]; // 定义temp指针,指向要删除元素的存储单元
if (_index < size) // 把该元素后面的所有元素向前移动一位
{
for (int i=_index; i<size; i++)
elements[i] = elements[i+1];
cout<<"移除成功"<<endl;
}
else
cout<<"下标越界"<<endl;
size--;
if (size <= capcity/2) // 判断是否需要释放多余空间
{
cout<<"为您释放多余空间" <<endl;
Person* *str = elements;
elements = new Person*[capcity/2];
for (int i=0; i<size; i++)
elements[i] = str[i];
}
return *temp; // 返回被删除元素的存储单元
}
ostream & operator <<(ostream & os,const PersonSet &ps){
cout<<"目前元素信息是"<<endl;
for (int i=0; i<ps.size; i++)
os<< *(ps.elements[i]) <<endl;
cout<<"================================"<<endl;
return os;
}
四、main函数
#include "Person.h"
#include "PersonSet.h"
#include <iostream>
int main(int argc, const char * argv[]) {
Person *p1 = new Person((char*)"1111",1); // 创建多个Person对象
Person *p2 = new Person((char*)"2222",2);
Person *p3 = new Person((char*)"3333",3);
Person *p4 = new Person((char*)"4444",4);
PersonSet ps; // 定义一个 PersonSet对象
ps.addPerson(*p1); // 将上述Person对象加入到ps中
ps.addPerson(*p2);
ps.addPerson(*p3);
cout << ps <<endl; // 至此,打印一下目前数据
ps.addPerson(*p4);
cout << ps <<endl; // 再打印一下目前数据
/*********以下代码根据不同需求,打开不同注释运行即可********/
// 测试迭代
// for (int i=0; i<ps.get_size(); i++) {
// cout<< ps.nextElement() <<endl;
// }
// cout<< ps.nextElement() <<endl;
// cout<< ps.nextElement() <<endl;
//移除最后一个元素测试
// cout<< ps.removeElement() << endl;
// cout << ps <<endl;
// delete p4;
// p4 = NULL;
//移除指定下标的元素
// ps.removeElement(0);
// ps.removeElement(0);
// ps.removeElement(0);
// cout << ps <<endl;
// delete p1;
// p1 = NULL;
return 0;
}
提示:
一定要避免出现野指针,另外指针被弃用后,要释放其存储空间,并让它指向0号存储单元,以防内存泄露。