C++ 构造函数和析构函数,以及拷贝构造详解

构造函数和析构函数是特殊函数,构造函数的主要作用是初始化类成员变量,析构函数恰恰相反,是释放类成员变量内存。

在实例化对象时,编译器会自动调用构造和析构函数,生成一个无参的默认构造函数。

但是,自己定义构造函数后,编译器便不会自动调用构造和析构函数。

构造和析构函数格式

class demo
{
private:
    /* data */
public:
    demo(/* args */);
    ~demo();
};

demo::demo(/* args */)    //构造函数
{
}

demo::~demo()            //析构函数
{
}

通过上述代码可知:

构造函数没有返回值,可以有参数,函数名和类名相同。

析构函数没有返回值,也没有参数。

举例

class Person
{
private:
    int num;
    char *name;

public:
    Person()
    {
        this->num = 10;
        name = NULL;
    }
    ~Person()
    {
        if (this->name != NULL)
        {
            delete []name;    //释放
        }
    }

拷贝构造

我的理解是在实例化第一个对象后,对其进行赋值,然后再实例化第二个对象,将第一个对象中分配的空间、内容分配到第二个对象(若有不对请指正)

普通的拷贝构造:(Person Jack (Tom);)或者(Person Jack = Tom;)

注意不能用(Person Jack;        Person Tom;        Jack = Tom;)

    Person(const Person &obj) // 拷贝构造
    {
        this->num = obj.num;
    }
    void setNum(int num)
    {
        this->num = num;
    }

    int main()
    {
    Person tom;
    tom.setNum(666);
    Person jack(tom);
    }

此时jack对象的num也是666

但是当拷贝的变量有指针时,会有一种情况,比如我给tom一个名字(指针),赋值tom,然后拷贝构造至jack,此时jack.name也是tom,然后我对它修改成jack,会发现tom的name也变为了jack。

这是因为我们在拷贝时,实质上是让两个对象的指针都指向第一个tom,因此对它修改时,二者的值都会变化,这叫浅拷贝

所以我们可以在进行构造时重新分配一个内存空间,避免这种情况,这就是深拷贝

深拷贝

#include <iostream>
#include <string.h>
using namespace std;
class Person
{
private:
    int num;
    char *name;

public:
    Person()
    {
        this->num = 10;
        name = NULL;
    }
    ~Person()
    {
        if (this->name != NULL)
        {
            //cout << "+++++" << endl;
            delete []name;
        }
    }
    Person(const Person &obj) // 拷贝构造
    {
        this->num = obj.num;
        // 分配内存(深拷贝)
        this->name = new char[20];
        strcpy(this->name, obj.name);
    }
        void setNum(int num)
        {
            this->num = num;
        }
    void setName(char *name)
    {
        this->name = new char[20];
        strcpy(this->name,name);
        //this->name = name;
    }
    void getDate()
    {
        cout << this->name << ":" << num << endl;
    }
};

int main()
{
    Person tom;
    char name1[] = {"tom"};
    char name2[] = {"jack"};
    char *p = name1, *fp = name2;
    tom.setNum(666);
    tom.setName(p);
    tom.getDate();
    Person jack(tom);
    jack.getDate();
    jack.setName(fp);
    tom.getDate();
    jack.getDate();
}

浅拷贝和深拷贝的主要差别就是有没有分配内存空间,要特别注意这一点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值