4.2.1 构造函数和析构函数

说明

对象的初始化和清理也是两个非常重要的安全问题

一个对象或者变量没有初始状态,对其使用后果是未知。

同样的使用完一个对象和变量,没有及时清理,也会造成一定的安全问题。

C++利用了构造函数和析构函数解决了上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。对象的初始化和清理工作是编译器强制要我们做的事情,因此我们如果不提供构造和析构,编译器会提供编译器提供的构造函数和析构函数是空实现。

  • 构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无需手动调用。
  • 析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。

构造函数语法类名(){}

  1. 构造函数,没有返回值也不写void
  2. 函数名称与类名相同
  3. 构造函数可以有参数,因此可以发生重载
  4. 程序在调用对象时候会自动调用构造,无需手动调用,而且只会调用一次

析构函数语法:~类名(){}

  1. 析构函数,没有返回值也不写void
  2. 函数名称与类名相同,在名称前加上符号~
  3. 析构函数不可以有参数,因此不可以发生重载
  4. 程序在对象销毁前会自动调用析构,无需手动调用,而且只会调用一次

示例代码

# include <iostream>
using namespace std;

class Person
{
public:
    Person()
    {
        cout << "构造函数的调用!" << endl;

    }

    ~Person()
    {

        cout << "析构函数的调用!" << endl;
    }

};

//构造和析构都是必须有的实现,如果我们自己不提供,编译器会提供一个空实现的构造和析构
void test01()
{
    Person p;                   //在栈上的数据,test01执行完毕后,释放这个对象                                 
}

int main()
{
    //test01();     //test01函数调用完之后,析构函数释放
    Person p;       //此行代码调用完之后,接着执行下一行,直到main函数执行完,才会释放析构代码                
    system("pause");
    return 0;

}

4.2.2 构造函数的分类和调用

两种分类方式

  1. 按参数分为:

    • 有参构造

    • 无参构造

  2. 按类型分为

    • 普通构造

    • 拷贝构造

三种调用方式

  1. 括号法
  2. 显示法
  3. 隐式转换法

示例代码

#include <iostream>
using namespace std;

//1. 构造函数的分类及调用
// 分类
// 按照参数分类   无参构造和有参构造
class Person
{
public:

    Person()
    {
        cout << "Person构造函数的调用!" << endl;
    }

    Person(int a)
    {
        age = a;
        cout << "Person有参构造函数的调用!" << endl;
    }

    ~Person()
    {
        cout << "Person析构函数的调用!" << endl;
    }

    //拷贝构造函数
    Person(const Person &p)
    {
        cout << "Person拷贝构造函数的调用!" << endl;
        //将传入的人身上的所有属性,拷贝到我身上
        age = p.age;
    }

    int age;

};

void test01()
{
    //1.括号法
    /*Person p1;                    //默认构造函数调用
    Person p2(10);              //有参构造
    Person p3(p2);              //拷贝构造函数调用*/

    //注意事项1
    //调用默认构造函数时候,不要加()
    //因为下面这行代码编译器会认为一个函数的声明,不会再创建对象
    //Person p1();

    /*cout << "p2的年龄:" << p2.age << endl;
    cout << "p3的年龄:" << p3.age << endl;*/

    //2.显示法
    //Person p1;
    //Person p2 = Person(10);           //有参构造
    //Person p3 = Person(p2);           //构造函数

    //Person(10);     //匿名对象  特点:当前行执行结束后,系统会立即回收掉匿名对象
    //cout << "aaaaa" <<endl;

    //注意事项2
    //不要利用拷贝构造函数 初始化匿名对象    编译器会认为Person(p3) == Person p3;对象重定义
    //Person(p3);

    //3.隐式转换法
    Person p4 = 10;           //其实相当于写了 Person p4 = Person(10);   有参构造
    Person p5 = p4;          //拷贝构造 Person p5 = person(p4);
}

int main()
{
    test01();
    system("pause");
    return 0;
}

易碎

易碎

我看到的今夜的星空,是几万年前的光,我眼中的你是此时的你!

0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注

网站ICP备案皖ICP备2024045222号-1