C++ 类中的 构造函数、拷贝构造函数、析构函数

本文详细介绍了构造函数的概念、特点和作用,包括默认构造函数、构造函数的重载以及如何通过构造函数初始化类成员。接着,解释了拷贝构造函数的功能,即通过一个已存在的对象初始化新对象。最后,阐述了析构函数的原理,它在对象生命周期结束时自动调用,释放资源。通过实例展示了这三种函数在实际编程中的使用情况。
摘要由CSDN通过智能技术生成

一、构造函数


① 概念

	构造函数就是和类名一样,而且是没有返回值的函数。如下所示:
	    
	class demo_class
	{
	public:
	    demo_class();//构造函数 如果不指定属性,则默认为私有的
	};

如果类里面的构造函数demo_class是私有的,那样就会编译器就会报错。如下图所示:
在这里插入图片描述

② 特点

① 如果自己没有定义构造函数,则编译器会使用默认构造函数。
② 默认的构造函数是一个空的函数。
③ 构造函数可以重载,只需要通过形参的不同辨别即可。

构造函数会在定义类对象是自动被调用,所以有初始化类成员数据的作用。同时构造函数不能是私有的。

以下代码是构造函数的初始化作用以及重载的实例:

#include <iostream>
using namespace std;
class demo_class
{
public:
    string string_data;
    demo_class();//构造函数 默认为私有类
    demo_class(string string_data);
};

demo_class::demo_class()
{
    cout<<我是来打酱油的构造函数!<<endl;
}

demo_class::demo_class(string string_data)
{
    cout<<我是来初始化类中的string_data成员的!<<endl;
    this->string_data = string_data;
}

注意!当是以下形式定义demo_class类对象时,只有打酱油的构造函数会自动启动!

int main()
{
    demo_class demo_obj;//这样定义对象则只会调用打酱油的构造函数
    return 0;
}

注意!当是以下形式定义demo_class类对象时,只有初始化string_da的构造函数会自动启动!

int main()
{
    demo_class demo_obj(旦丁在此!);//把demo_obj类对象中的string_data初始化为 “旦丁在此”    
    cout<<demo_obj.string_data<<endl;
    return 0;
}

以下代码是构造函数的初始化列表


#include <iostream>
using namespace std;

class demo_class
{
public:
    int    int_data;
    string string_data;
    demo_class():int_data(100),string_data("旦丁在此!"){}//构造函数 初始化列表
};

int main()
{
    demo_class demo_test;

    cout<<demo_test.int_data<<demo_test.string_data<<endl;
    
    return 0;
}

初始化列表也常用于私有成员的初始化!

运行结果:

100旦丁在此!

二、拷贝构造函数

① 概念

和构造函数一样,唯一不同的时拷贝构造函数有形参,该形参接收一个该类的对象。具体如下所示:

class demo_class
{
    public:
        string string_data;
        demo_class();//构造函数 默认为私有类
        demo_class(string string_data);
        demo_class(demo_class const &tmp_dome);
};

② 作用

拷贝构造函数中的拷贝可以理解成赋值,把一个类对象赋值给另外一个对象。(简单点来说就是把形参的对象赋值给你定义的对象),
也就是初始化类对象的作用。具体写法如下:

class demo_class
{
    public:
        string string_data;
        demo_class();//构造函数 默认为私有类
        demo_class(string string_data);
        demo_class(demo_class const &tmp_dome);//拷贝构造函数
};


demo_class::demo_class(const demo_class  &tmp_demo)
{
    string_data = tmp_demo.string_data;
}
int main()
{
   demo_class demo_obj_one("旦丁在此!");//定义一个被拷贝的对象
   demo_class demo_obj_two;//调用拷贝构造函数,把demo_obj_one对象拷贝给demo_obj_two对象
   cout<<demo_obj_two.string_data<<endl; //验证字符串是否拷贝到demo_obj_two对象中
    return 0;
}

运行结果

我是来初始化类中的string_data成员的!
旦丁在此!

三、析构函数

① 概念

析构函数的理解刚好和构造函数相反,他是在类的周期结束是会被自动调用(也就是用完之后自动调用)。
析构函数是构造函数前面加个~。
详细一点应该这样说:当类离开了他的域或者delete释放了一个类的空间,析构函数就会自动被调用。
当delect一个类对象指针时,析构函数也会自动被调用

② 例程示例1:当类离开了他的域,析构函数就会自动被调用。


#include <iostream>
using namespace std;
class demo_class
{

public:
    ~ demo_class()
    {
        cout<<"我歇逼了!"<<endl;
    }

    int fun()
    {
        cout<<"我的域还没结束!"<<endl;
    }
};

int main()
{
    demo_class demo_testp;
    demo_testp.fun();

    return 0;
}

运行结果:

我的域还没结束!
我歇逼了!

析构函数比成员函数fun慢调用,以上代码不难理解类对象的域。

② 例程示例2:当delect一个类对象指针时,析构函数也会自动被调用


#include <iostream>


using namespace std;




class demo_calss
{
public:
    ~demo_calss();
};


demo_calss::~demo_calss()
{
    cout<<"我歇逼了"<<endl;
}


int main()
{
    //定义一个类对象指针,并且给其申请内存空间
    demo_calss * demo_class_p = new demo_calss;
    cout<<"我的域还没结束?"<<endl;
    delete(demo_class_p);
    return 0;
}

运行结果:

我的域还没结束?
我歇逼了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值