类对象的四个隐藏函数

本文详细介绍了C++中类对象的构造函数、析构函数、拷贝构造函数和赋值操作函数的工作原理及使用场景。包括构造函数的初始化列表、析构函数的资源释放、拷贝构造中的浅拷贝与深拷贝问题,以及赋值操作函数的注意事项。特别强调了在涉及指针和内存管理时,为何需要显式实现这些特殊函数来确保正确操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、构造函数

    构造函数是类的同名成员函数,没有返回值,当实例化对象时它会自动执行,一般负责对类进行初始化、分配资源

    class 类名

    {

        int* p;

    public:

        类名(参数)

        {

            p = new int;  

        }

    };

    1、构造函数必须是public 否则无法实例化对象

    2、构造函数可以重载,可以有多个版本

    3、带参数的构造函数的调用方法:

        类名  对象名(实参);

        类名* 对象指针 = new 类名(实参);

    4、默认情况下编译器会自动生成一个无参构造函数,该函数什么都不做,一旦显示地实现了构造函数,则编译器不生成该函数

        类名 对象名;   //调用无参构造,如果没有无参构造则报错

    5、也可以通过设置构造函数的默认形参达到无参构造的效果

    6、构造函数没有返回值

    7、不要使用malloc为类实例化对象分配内存,因为malloc不会调用构造函数

二、、析构函数

    析构函数负责对类对象进行收尾工作,例如:释放类中的资源、保存数据等,当类对象销毁时会自动调用执行

 class 类名

    {

        int* p;

    public:

        类名(参数)

        {

            p = new int;

        }

        ~类名()

        {

            delete p;

        }

    };

    1、析构函数也必须是 public

    2、没有返回值、参数、不能重载

    3、当类对象生命周期完结、或者使用delete销毁对象时会自动调用析构函数

    4、如果没有显示地实现析构函数,编译器也会自动生成一个什么都不干的析构函数

    5、构造函数肯定会执行,但是析构函数不一定执行

    6、不要使用free来销毁对象,不会执行析构函数


 

        初始化列表

    初始化列表是构造函数的一种特殊语法,只能在构造函数中使用

    class 类名

    {

    public:

        类名(参数):成员名1(初始化数据),成员名2(初始化数据)...

        {

            //构造函数

        }        

    };

    1、类的成员变量在老编译标准中不可以设置初始值的,而且在构造函数之前成员变量都已经定义完毕,因此const属性的成员

    变量无法在构造函数内正常赋值初始化(新标准中可以直接设置初始值,但是也只能给常量,功能有限)

    2、初始化列表先于构造函数执行的,初始化列表执行时类对象还没有构造完成,因此它是唯一(老标准)一种能给const属性成员变量赋值的方法

    3、当参数名与成员名相同,初始化列表可以自动分解成员名和参数名

    4、当类中有类类型成员时,该成员的有参构造函数也可以在初始化列表中被执行
 

    三、拷贝构造

        拷贝构造是一种特殊的构造函数,格式为

            类名(const 类名& that)  //const不是必写的,加了更好

            {

            }

            什么时候会调用拷贝构造:当使用旧对象给新对象进行初始化时,会自动调用拷贝构造

            Test t;

            Test t1 = t;

            拷贝构造的任务:

                顾名思义拷贝构造负责把旧对象中的成员变量拷贝给新对象,且编译器会默认生成具备这样功能一个隐藏的拷贝构造函数

            什么时候应该显示地实现拷贝构造:

                普通情况下编译器自动生成的拷贝构造完全够用,但是当类中的成员有指针且为指针分配了堆内存,默认的拷贝构造

                只会对指针的值进行拷贝,这样就导致两个对象的指针成员都指向同一块堆内存,在执行析构函数时会造成重复

                释放堆内存崩溃,此时就应该显式地实现拷贝构造

            浅拷贝和深拷贝:

                当类中有成员是指针类型且分配了堆内存,浅拷贝只会拷贝指针变量的值;深拷贝不拷贝指针变量的值,而是申请新的内存,

                拷贝内存中的内容到新内存中

       

       

        四、赋值操作函数:

            所谓的赋值操作,就是一个对象给另一个对象赋值(俩对象都已经创建完毕),在C++中会把运算符当作函数处理,使用运算符

            相当于调用运算符函数

            void operator=(const 类名& that)

            {

            }

            Test t1, t2;

            t1 = t2;  //调用赋值操作

        赋值运算符函数的任务:

            它与拷贝构造的任务基本一致,默认下编译器也会自动生成具备浅拷贝功能的赋值操作函数,但是当需要进行深拷贝时不仅需要

            显式实现拷贝构造,同时也需要显式地实现赋值运算符函数

        实现赋值运算符函数需要注意的问题:

            赋值运算符函数与拷贝构造函数任务虽然接近,但是实现过程有所不同:

            问题1:  两个对象的指针都已经分配好内存

                    a、先释放被赋值者的指针变量所指向的原内存

                    b、再给被赋值者的指针变量重新申请内存

                    c、把赋值者指针变量所指向内存的内容拷贝给赋值者新申请的内存中

            问题2:  有可能对象自己给自己赋值

                    需要判断this和赋值者的地址是否相同,如果相同立即结束,不相同才进行赋值操作

            问题3:  允许 n1 = n2 = n3 连续赋值操作

                    因此赋值运算符函数的返回值要返回类对象的引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoyu1381

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值