C/C++ 对象的添加与删除(二)

前言: 文章 对象的添加与删除(一) 只是简单的操作练习。那么这篇文章就带大家一起深入探讨动态内存分配、构造函数 和 析构函数的应用。

一、要求与说明

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号存储单元,以防内存泄露

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值