C++拷贝构造函数之浅拷贝与深拷贝

构造函数按照有无参数,可分为有参构造函数和无参构造函数,按照函数类型,可分为普通构造函数和拷贝构造函数。在类中,如果我们不写拷贝构造函数,则编译器编译时会自动帮我们加上一个默认的拷贝构造函数,从而使我们可以使用拷贝对象,若我们写了拷贝构造函数,则系统不会再给我们加默认的拷贝构造函数。

系统默认的拷贝构造函数在拷贝时为浅拷贝,拷贝指针变量时,并不拷贝指针指向的值,而只拷贝指针指向值的地址。此时易出现问题,当我们的类中有堆中数据时(new int),需要我们在析构函数中手动释放掉内存,此时系统会崩溃,原因如下:

test()函数中我们定义的第二个person是通过拷贝函数定义的,而我们没有写拷贝构造函数,使用的为默认的拷贝构造函数,为浅拷贝,拷贝height指针时,并没有在堆区开辟新的地址,而是在栈区开辟了一个地址,其值为height指向值的地址,此时tian.height存储的地址与tian2.height存储的地址相同,均指向最开始有参构造函数开辟的那块内存,存储的数据为“173”。当test()函数执行完的时候,会释放栈区的内存,此时要销毁我们创建的两个对象,将调用类中的析构函数(栈中先进后出,先执行tian2的析构函数),由于我们在析构函数中有delete操作,delete操作会将堆区存储的数据释放(并不会清零,而是变为一个没有意义的数),之后又执行tian的析构函数,又将释放一边堆区存储的数据,从而出现了重复释放的问题,导致系统崩溃。

改进措施为:自己写一个拷贝构造函数(Person(int age, int height)),进行深拷贝,拷贝时直接在堆区开辟新的地址来存储数据。

代码如下:

#include <iostream>

using namespace std;


class Person

{

public:

    Person()

    {

        cout << "无参构造函数" << endl;

    }

    Person(int age, int height)

    {

        cout << "有参构造函数" << endl;

        this->age = age;

        this->height = new int(height);

    }

    ~Person()

    {

        cout << "析构函数" << endl;

        if (height != NULL)

        {

            delete height;

            height = NULL;

        }

    }

    int age;

    int* height;

};


void test()

{

    Person tian(22,173);

    Person tian2(tian);

}


int main()

{

    test();

    return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计并实现一个动态整型数组类Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数中按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。 设计并实现一个动态整型数组类Vect,要求: (1)实现构造函数重载,可以根据指定的元素个数动态创建初始值为0的整型数组,或根据指定的内置整型数组动态创建整型数组。 (2)设计拷贝构造函数析构函数,注意使用深拷贝。 (3)设计存取指定位置的数组元素的公有成员函数,并进行下标越界,若越界则输出“out of boundary”。 (4)设计获取数组元素个数的公有成员函数。 (5)设计用于输出数组元素的公有成员函数,元素之间以空格分隔,最后以换行符结束。 在main函数中按以下顺序操作: (1)根据内置的静态整型数组{1,2,3,4,5}构造数组对象v1,根据输入的整型数构造数组对象v2。 (2)调用Vect的成员函数依次输出v1和v2的所有元素。 (3)输入指定的下标及对应的整型数,设置数组对象v1的指定元素。 (4)根据数组对象v1拷贝构造数组对象v3。 (5)调用Vect的成员函数依次输出v1和v3的所有元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值