C++之对象数组+对象成员+拷贝构造函数(深/浅)

对象数组

实例(栈中实例化和堆中实例化):

class Coordinate
{
public:
    int m_iX;
    int m_iY;
};

int main()
{
    Coordinate coord[3];//栈中实例化
    coord[1].m_iX = 10;
    Coordinate *p = new Coordinate[3];//堆中实例化
    p[0].m_iY = 20; //p->m_iY = 20
    delete[]p;
    p = NULL;
    return 0;
}

上述代码在内存中的工作:
C++之对象数组+对象成员+拷贝构造函数(深/浅)_第1张图片

在这里有一个小问题需要注意一下,在使用new申请数组空间后,要用delete[]p来释放掉内存,注意一定不要忘掉[],那么是为什么呢?
其实我们在申请一个对象数组时,分别调用了n次构造函数,那么我们在释放时同样要调用n次析构函数,如果忘掉[],那么只销毁指向指针的第一个元素。

对象成员
在实际的应用中,对象包含对象是一种很常见的状态,比如一间屋子里有家具,以点和线为例:

class Coordinate//坐标系上的点
{
public:
    Coordinate();
private:
    int m_iX;
    int m_iY;
};

class Line//坐标系上的线
{
public:
    line();
private:
    Coordinate m_coorA;
    Coordinate m_coorB;
};

int main()
{
    Line *p = new Line();
    delete p;
    p = NULL;
    return 0;
}

这里有个实例化顺序的问题,在上述代码中,先实例化点还是先实例化线呢?
答案是在实例化线的时候先去示例化A点,其次B点,最后实例化线,在销毁时正好与创建的过程相反,就好比组装一辆车,得先把零件做好才能组装,同样拆毁一辆车,是把整辆的车拆成一个个的小部件。

拷贝构造函数

拷贝构造函数分为深拷贝和浅拷贝,下面来看两段代码。
代码1:

class Array
{
public:
    Array(){m_iCount=5;}
    Array(const Array& arr)
    {
        m_iCount=arr.m_iCount;
    }
private:
    int m_iCount;
};
int main()
{
    Array arr1;
    Array arr2=arr1;
    return 0;
}

代码2:

class Array
{
public:
    Array()
    {
        m_iCount = 5;    //构造函数,指向堆申请的内存
        m_pArr = new int[m_iCount];
    }
    Array(const Array& arr)//拷贝构造函数
    {
        m_iCounta = arr.m_iCount;
        m_pArr = arr.m_pArr;
    }
private:
    int m_iCount;
    int *m_pArr;//指针
};

int main()
{
    Array arr1;
    Array arr2 = arr1;//这种情况下,浅拷贝
    return 0;
}

这两个代码的共同点都是只是将数据成员的值进行了简单的拷贝,我们把这种拷贝模式称之为浅拷贝,对于第一个代码来说是没有问题的,但是对于第二个代码存在着很大的问题。
C++之对象数组+对象成员+拷贝构造函数(深/浅)_第2张图片

如上图所示,代码2中arr1的指针和arr2的指针指向同一块内存,当改变arr1的内存数值,arr2的内容也势必改变,最严重的是当arr1和arr2都释放时,势必会对同一内存释放两遍,面对这种问题,会引起计算机的崩溃。而我们希望拷贝构造函数所完成的工作是如下图所示的:
C++之对象数组+对象成员+拷贝构造函数(深/浅)_第3张图片

拷贝的内容不是将指针的地址简单的拷贝过来,而是将指针指向内存中的每一个元素都拷贝过来,为了实现这种方法,代码2应该写成如下模样,即深拷贝
代码2+:

class Array
{
public:
    Array(){ m_iCount = 5; m_pArr = new int[m_iCount]; }//构造函数,指向堆申请的内存
    Array(const Array& arr)//拷贝构造函数,深拷贝
    {
        m_iCounta = arr.m_iCount;
        m_pArr = new int[m_iCount];
        for (int i = 0; i < m_iCount; i++)
        {
            m_pArr[i] = arr.m_pArr[i];
        }
    }
private:
    int m_iCount;
    int *m_pArr;//指针
};

int main()
{
    Array arr1;
    Array arr2 = arr1;//这种情况下,浅拷贝
    return 0;
}

你可能感兴趣的:(c++,C++,学习)