更详细的 内存分配、扩充内存、析构函数、迭代、操作符重载等内容,可以参考 C/C++ 对象的添加与删除(二)

一、编程要求:

1、定义一个Date类:
变量:年,月,日
函数:构造函数,获取函数,设置函数,输出函数

2、 定义一个Person类:
变量:组合,Date d,*name,*address
函数:构造函数,析构函数,输出函数

3、普通函数(不属于以上两个大类,以防误解):
addPerson函数,把对象添加到array
showArray函数,把数组中所有的Person信息展示
delPerson函数,删除_index对象

4、测试:创建5个Person对象
调用addPerson函数,把对象添加到array
调用showArray函数,把数组中所有的Person信息展示
调用delPerson函数,删除数组中index位置的Person

二、Date类

class Date{ 
private:
    int year;
    int month;
    int day;
public:
    // 构造函数
    Date(int _year,int _month,int _day):year(_year),month(_month),day(_day){}   
    // 获取函数
    int getYear()const  { return year; }    
    int getMonth()const { return month; }
    int getDay()const   { return day ; }
    // 设置函数
    void setYear(int _year)   { year = _year; }     
    void setMonth(int _month) { month = _month; }
    void setDay(int _day)     { day = _day; }
    // 输出函数
    void date_print(){      
        cout<<"year is "<<year<<endl;
        cout<<"month is "<<month<<endl;
        cout<<"day is "<<day<<endl;

三、Person类

class Person{
private:
    Date d; 			// 表示一个人的出生日期,组合
    char *name ;		// 指针,堆空间
    char *address; 		// 地址,堆空间
public:
	// 构造函数
    Person(int _year,int _month,int _day,char *_name,char *_address):d(_year,_month,_day){ //构造函数
        this->name = new char[strlen(_name)+1];
        this->address = new char[strlen(_address)+1];
        strcpy(this->name, _name);
        strcpy(this->address, _address);
    // 析构函数
    ~Person(){
        if (name != NULL) 
            delete []name;
            cout<<"free..."<<endl;
            name = NULL;
        if (address != NULL) 
            delete []address;
            address = NULL;
	// 输出函数
    void person_print(){  
        d.date_print();
        cout<<"name is "<<name<<endl;
        cout<<"address is "<<address<<endl<<endl;

四、普通函数

提示: 这段代码不需要放在任何一个类里面,它只是一个普通函数,可以放在公共部分。

void addPerson(int &_size,int &_capcity,Person **_array,Person &_p){ 
    if (_size < _capcity)
        _array[_size ++] = &_p;
 //把数组中所有的Person信息展示
void showArray(int &_capcity,Person** _array){      
    for(int i=0; i<_capcity; ++i)
        (*_array[i]).person_print();
//删除下标_index对象
void delPerson(int _index,int &_size ,Person**_array){   
    if (_index < _size) 
        _size --;
        for (int i=_index; i<_size; i++ )
            _array[i] = _array[i+1];

五、main函数

int main(int argc, const char * argv[]){
 	//按要求创建5个Person对象,
    Person p1(2007,6,18, (char*)"Jamas" ,(char*)"Cavas");   
    Person p2(2011,6,24, (char*)"Wade"  ,(char*)"Heat");
    Person p3(2012,6,20, (char*)"Bosh"  ,(char*)"Heat");
    Person p4(2013,5,31, (char*)"Alen"  ,(char*)"Thunder");
    Person p5(2016,6,23, (char*)"Irving",(char*)"Cavas");
    int capcity = 5;    //总共可以存储多少个元素
    int size = 0;       //目前已经存储了多少个元素  
    Person* *array = new Person*[capcity]; 
    //调用addPerson函数,把对象添加到array
    addPerson(size, capcity, array, p1);  
    addPerson(size, capcity, array, p2);
    addPerson(size, capcity, array, p3);
    addPerson(size, capcity, array, p4);
    addPerson(size, capcity, array, p5);
 	//调用showArray函数,把数组中所有的Person信息展示
    showArray(capcity, array);     
    //手动输入要删除的下标
    cout<<"删除下标对象?"<<endl;   
    int n;
    cin>>n;
 	//调用delPerson函数,删除数组中index位置的Person
    delPerson(n, size, array);   
    showArray(size, array);
    delete []array;
    array = NULL;

值得一读的话,都有源码哦:

另一篇文章 C/C++ 对象的添加与删除(二),更详细的讲述了添加和删除对象时,内存的分配、释放、构造函数、析构函数、运算符重载 和 迭代器 等操作。希望对你有帮助。

migc小型简单的库,使用mimalloc API实现保守的GC。 功能小巧。 与mi migc链接时,libmigc.so仅为20KB。小而简单的库使用mimalloc API实现了保守的GC。 功能小巧。 与mimalloc链接时,libmigc.so仅为20KB。 具有C中保守性GC的大多数用户所需的API,并且可以在简单情况下(例如,在不需要精确标记的情况下)替换BDWGC。有:migc_add_roots和migc_delete_roots用于添加删除指针范围以扫描潜在的指针,migc_register_finalizer用于在死对象上调用终结器。 快速分配。 对象的初始化和清理是两个非常重要的安全问题,创建一个对象而没有初始化,使用的后果将是未知的,使用完一个对象而没有及时清理,也会造成一定的安全问题。C++利用构造函数和析构函数解决上述问题,它们将会被编译器自动调用,完成对象初始化和清理工作。 这样就声明了一个ClassName类型的object对象C++会为它分配足够的存放对象所有成员的存储空间。 注意:为节省存储空间,C++创建对象时仅分配用于保存数据成员的空间,而类中定义的成员函数则被分配到存储空间中的一个公用区域,由该类的所有对象共享。 例如,我定义了一个这样的类: class Rec remove函数在STL中的源码如下: template OutputIterator remove_copy ( InputIterator first, InputIterator last, OutputIterator result,const T& value ) ​ C++利用了构造函数和析构函数解决上述问题,这个函数将会被编译器自动调用,完成对象初始化和清除工作。: 当对象p2释放内存是会把堆区的内存也一起释放,但是当轮到对象p1是否内存是,堆区的内存已经释放了,以此造成错误。​ 1.如果用户定义有参构造函数,c++不提供默认无参构造,但会提供默认拷贝构造。:主要作用于创建对象时为对象的成员属性赋值,构造函数有编译器自动调用,无需手动调用。​ 4.程序在调用对象时候会自动调用构造,无需手动调用,而且只调用一次。 C++利用构造函数和析构函数解决上述问题,这两个函数会被编译器自动调用,完成对象初始化和清理工作。对象的初始化和清理工作是编译器强制要我们做的事情,因此如果我们不提供构造和析构,编译器会提供。对象的初始化和清理是两个非常重要的安全问题,一个对象或者变量没有初始状态,对其使用后果是未知的;利用编译器提供的拷贝构造函数,会做浅拷贝操作,浅拷贝带来的问题是堆区的内存的重复释放。(4)程序在调用对象时候会自动调用构造,无需手动调用,而且只会调用一次。(3)析构函数不可以有参数,因此不可以发生重载; 前言: 文章 对象添加删除(一) 只是简单的操作练习,包括内存管理都是简单的浅拷贝。那么这篇文章就带大家一起深入探讨动态内存分配、构造函数 和 析构函数的应用。 要求与说明: 创建一个Person类,属性包括姓名和年龄,并重载运算符输出Person对象。之后创建一个PersonSet类,用来添加删除或查找Person对象,要求可以动态开辟和释放存储空间。 最后在main函数中测试实例。 本文... 如果不知道具体的场景,即元素保存在什么样的容器中,是不能从序列中移除元素的。因此,“移除元素的”算法也无法做到这一点,它们只会重写被选择的元素或者忽略复制的元素。移除操作不会改变被“移除”元素的序列的元素个数。 有 4 种移除算法: remove() 可以从它的前两个正向迭代器参数指定的序列中移除和第三个参数相等的对象。基本上每个元素都是通过用它后面的元素覆盖它来实现移除的。它会返回一个指向新的最后一个元素之后的位置的迭代器。 remove_copy() 可以将前两个正向迭代器参数指定的序列中的元素复制 如果某个对象是其他对象的数据成员,这一顺序也适用。因此,按对象的销毁顺序与创建顺序相反这一原则,数据成员对象的销毁顺序与其在类中声明的顺序相反。例如下面对象a先于b创建,所以a先入栈,b后入栈,那么销毁时候b先销毁,a后销毁。析构函数是一个方法,它的名称与类名相同,前缀加上‘~’符号,并且不返回任何内容。在没有智能指针的帮助下,在堆上分配的对象不会自动销毁,必须显示的调用delete,从而调用析构函数并释放内存。当栈中的对象超出作用域的时候,对象会被销毁。当销毁对象时,会发生两件事情,调用对象的。 在C++中,我们应该经常会用到new、delete,它们是C++一个关键字,同时也是一个操作符,下面我将我对这两者的了解和学习做一个总结和探讨。new和delete的全过程首先我们定义一个对象A: struct A { size_t h; };当我们使用关键字new在堆上动态创建一个对象A时,比如 A* p = new A(),它实际上做了三件事: 向堆上申请一块内存 对于计算机程序设计而言,变量和对象在内存中的分配都是编译器在编译程序时安排好的,这带来了极大的不便,如数组必须大开小用,指针必须指向一个已经存在的变量或对象。对于不能确定需要占用多少内存的情况,动态内存分配解决了这个问题。 对于个人感触最深的就是数组了,数组有三个重要的限制:(1)数组长度固定不变;(2)在编译时必须知道数组的长度;(3)数组只在定义它的块语句内存在。实际的程序往往不能忍受这