C++ 构造函数和析构函数

构造和析构

构造函数

定义: C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数

“`c++
class 类名{
类名(形参){
构造体
}
}
* 比如:

class A
{
    A(形参)
    {

    }
}
#define _CRT_SECURE_NO_WARNING
#include "stdafx.h"
using namespace std;

class Test
{
public:
    Test(int x, int y)  //Test类的构造函数,作用:在对象被创建时用来初始化对象的函数(函数可以被重载)
    {
        m_x = x;
        m_y = y;
    }
    void Print_Point()
    {
        cout << "x = " << m_x << " ,y = " << m_y << endl;
    }

private:
    int m_x;
    int m_y;
};
int main()
{
    Test T1(1, 2);
    T1.Print_Point();
    return 0;
}

这里写图片描述

析构函数

~Test();  //析构函数没有形参,不能被重载

注意:析构函数和构造函数都没有返回值。

   什么时候用到析构函数呢?当对象T1是被在其他函数中使用的,那么执行完函数后T1被销毁前会触发析构函数。
   如果自己不在类中写构造函数,那么编译器在编译的时候就会默认构造无参构造函数。(其实就是一个空函数Test();)
   析构函数调用的顺序,跟构造相反,谁先构造的,谁后析构

拷贝构造函数

当我们需要用属于相同的类下的一个对象去初始化另一个对象时,需要用到拷贝函数。
比如在Test类中有如下一个拷贝函数,没有则系统默认:

Test(const Test &another)   //注意这里的&anoher表示引用
    {
        m_x = another.m_x;
        m_y = another.m_y;
    }

则在主函数中写以下语句可以实现用一个已初始化的对象去未初始化的对象。

Test t1(1,2);
    Test T1(t1);  //可以通过t1给T1赋值,与Test T1 = t1;等价

深拷贝和浅拷贝

在main函数中要实现一个对象向另一个对象实现拷贝,往往用以下语句:

int main()
{
    Teacher t1(1, "zhang3");
    Teacher t2(t1);
    return 0;
}

如果在类的定义中没有定义一个深拷贝函数,则编译器自动执行的将是浅拷贝函数,那么程序在执行时就会发生崩溃,原因如下:
* 编译器默认执行的浅拷贝函数:

Teacher(const Teacher &another)
{
    m_id = another.m_id;
    m_name = another.m_name;  //将t1的成员拷贝给t2时,t2的指针*name将指向t1的*name所指向的堆区空间
}

这里写图片描述
那么当执行完浅拷贝后,将析构函数,即释放掉t2中的*name所指向的堆区空间,所以t1中*name所指向的空间也不存在了,那么当析构t1时,程序就会报错。所以要使用深拷贝函数:

Teacher(const Teacher &another)    //实现深拷贝
    {
        m_name = (char*)malloc(sizeof(another.m_name));
        strcpy(m_name, another.m_name);
        m_id = another.m_id;
    }

这里写图片描述
完整程序如下:

#include "stdafx.h"
using namespace std;

class Teacher
{
public:
    Teacher(int id, char *name)
    {
        m_id = id;
        m_name = (char*)malloc(sizeof(name));
        strcpy(m_name, name);
    }

    void PrintT()
    {
        cout << "m_id = " << m_id << ", m_name = " << m_name << endl;
    }

    Teacher(const Teacher &another)    //实现深拷贝
    {
        m_name = (char*)malloc(sizeof(another.m_name));
        strcpy(m_name, another.m_name);
        m_id = another.m_id;
    }
    ~Teacher()
    {
        cout << "~Teacher()...." << endl;

    }


private:
    int m_id;
    char *m_name;
};

int main()
{
    Teacher t1(1, "zhang3");
    t1.PrintT();
    Teacher t2(t1);
    t2.PrintT();
    return 0;
}

编译结果如下:
这里写图片描述

构造函数的初始化列表

一个类的成员中有其他类的对象,那么要初始化这个对象,必须得把它写到初始化列表中。

class B
{
    public:
    B(A &a1,A &a2,int b):m_a1(a1),m_a2(a2)
    {
        m_b = b;
    }
    private:
    int m_b;
    A m_a1;
    A m_a2;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值