C++入门系列6:构造函数与析构函数


前言:C++入门系列文章,是按照鲍松山老师的C++入门课程进行的学习整理与记录,方便自己同时也方便一些编程新手,更好地去理解编程中许多概念和技术产生的原因,由来和发展过程,希望通过逻辑帮助自己更快也更长久地理解和应用。
  尊重原创,因此先附上鲍老师的视频链接:https://edu.51cto.com/course/4940.html,感谢鲍老师的精心备课,悉心讲解与耐心传授。

1 构造函数

1.1 构造函数产生的原因

上一节中我们创建了一个CGoods的类,在这里我们重新创建一个Test的类,这个类有2个私有变量,data, value,代码如下:

#include <iostream>
using namespace std;


class Test
{
public:
    void InitTest(int d = 0, int v = 0)
    {
        data = d;
        value = v;
    }
private:
    int data;
    int value;
};


int main()
{
    Test t1;
    t1.InitTest(100, 200);
    return 0;
}

由上图,当我们创建了一个Test的对象t1以后,t1的两个变量创建以后都是随机值,我们需要先对对象的变量进行赋值。
在C++中,如果数据成员为私有,要对它们进行初始化,必须用一个公有函数来进行。在t1调用公有函数InitTest后,t1的两个私有变量就初始化好了。

现在存在一个问题,以后的项目中我们需要创建多个对象,那是不是每次创建一个对象以后,我们都要手动调用一下自己写的初始化函数呢?这样是不是会比较麻烦

实际上,C++已经考量好这个问题了,即我们的构造函数:由于数据成员多为私有,要对它们进行初始化,必须用一个公有函数来进行。同时这个函数应该在且仅在定义对象时自动执行一次,称为构造函数(constructor)

构造函数的代码示例如下:

#include <iostream>
using namespace std;


class Test
{
public:
    //构造函数特性1,2:函数名与类名相同,且无返回类型
    Test()
    {
        cout << "Create Test Object: " << this << "(构造函数1:无参)" << endl;
    }

    //构造函数特性4:可以重载
    Test (int d)
    {
        cout << "Create Test Object: " << this << "(构造函数2:1个参数)" << endl;
        data = d;
    }

    Test(int d, int v);

private:
    int data;
    int value;
};

// 构造函数特性5,可以在类外实现
//实现类外函数的格式如下
// 返回值 类名::函数名(参数列表)
Test::Test(int d, int v)
{
    cout << "Create Test Object: " << this << "(构造函数3:3个参数)" << endl;
    data = d;
    value = v;
};


int main()
{
    Test t1;
    Test t2(10);
    Test t3(10, 20);
    return 0;
}

构造函数是特殊的公有成员函数,其特征如下:
1:函数名与类名相同;
2:构造函数无函数返回类型说明。注意是没有而不是void,即什么也不写,也不可写void!实际上构造函数有返回值,返回的就是构造函数所创建的对象;
3:在程序运行时,当新的对象被建立,该对象所属的类的构造函数自动被调用,在该对象生存期中也只调用这一次;
4:构造函数可以重载。严格地讲。说明中可以有多个构造函数,它们由不同的参数表区分,系统在自动调用时按一般函数重载的规则选一个参数表一致的进行执行;
5:构造函数可以在类中定义,也可以在类外定义;
6:如果类说明中没有给出构造函数,则C++编译器自动给出一个缺省的构造函数
  类名(void) {}
  但只要我们定义了一个构造函数,系统就不会自动生成缺省的构造函数。
  只要构造函数是无参的或者只要各参数均有缺省值的,C++编译器都认为是缺省的构造函数,并且缺省的构造函数只能有一个。
  如果对象的数据成员全为公有的,也可以在对象名后加“=”加“{}”,在花括号中顺序填入全体数据成员的初始值。

以上代码运行后的截图如下:
在这里插入图片描述

由上图,我们根据参数列表不同,一共构建了3个构造函数。
当我们创建t1,t2,t3对象时,自动调用了符合各自参数列表的构造函数。
注:以上编写构造函数的6个特征需要结合所给示例好好地深入地理解。

2 析构函数

  构造函数是为了在创建对象的同时完成对象的初始化的过程。那么如果我们在初始化的过程中做了一些分配内存之类的动作,那么我们是不是每一次都应该写一个函数来完成对应释放内存的动作呢。与构造函数相似,析构函数是对象在作用域过程中即将释放之前而对对象所做的善后工作。
  以上是我的简单理解,下面看一下析构函数的定义及特征:
  当一个对象定义时,C++自动调用构造函数建立该对象并进行初始化,那么当一个对象的生命周期结束时,C++也会自动调用一个函数注销该对象并进行善后工作,这个特殊的成员函数即析构函数(destructor):
1:析构函数与类名相同,但在前面加上字符‘~’,如~CGoods();
2:析构函数无函数返回类型,与构造函数在这方面是一样的。但析构函数不带任何参数。
3:一个类有一个也仅有一个析构函数,这与构造函数不同。析构函数也可以缺省。
4:对象注销时,系统自动调用析构函数。

在上面的Test类中添加了析构函数,并运行后的截图如下:
在这里插入图片描述由上图,我们之前创建的t1,t2,t3三个对象,按照先进后出的顺序进行了释放。

2.1 构造函数、析构函数趣味人生杂谈

  一个对象的构造与析构,与一个人的出生与死亡是极其相似的。
  你看一个对象在出生时,因为参数列表不同,可以有多个构造函数;恰似每一个人的出生,由于原生家庭不同,每一个人出生后所拥有的也完全不同,就如高官富商与普通百姓家的孩子从出生开始便有天地之差。
  而一个对象在释放之时,不带任何参数并且仅有一个析构函数;恰似每一个人在临死之际,无论生前是富贵显赫还是穷困潦倒,在析构之时,都带不了任何参数。
  松山老师的这个见解有趣也方便记忆构造与析构函数的特征,故在此一记。

3 本节小结

本节的重点是理解构造函数与析构函数存在的原因,以及编写C++这两个内在成员函数的特征规则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值