初谈构造函数和析构函数

news/2024/10/7 18:19:07 标签: c++

加油学习的一天~~>_<~~

文章目录

  • 目录

    文章目录

    前言

    一、什么是构造函数?

    二、析构函数

    (1)概念:

    总结



前言

构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并 不是开空间创建对象(我们常使⽤的局部对象是栈帧创建时,空间就开好了),⽽是对象实例化时初始化 对象。构造函数的本质是要替代我们以前Stack和Date类中写的Init函数的功能,构造函数⾃动调⽤的 特点就完美的替代的了Init。

析构函数与构造函数功能相反,析构函数不是完成对对象本⾝的销毁,⽐如局部对象是存在栈帧的, 函数结束栈帧销毁,他就释放了,不需要我们管,C++规定对象在销毁时会⾃动调⽤析构函数,完成对 象中资源的清理释放⼯作。析构函数的功能类⽐我们之前Stack实现的Destroy功能,⽽像Date没有 Destroy,其实就是没有资源需要释放,所以严格说Date是不需要析构函数的。


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是构造函数?

(1)析构函数的特点:

1. 析构函数名是在类名前加上字符~。

2. ⽆参数⽆返回值。(这⾥跟构造类似,也不需要加void)

3. ⼀个类只能有⼀个析构函数。若未显式定义,系统会⾃动⽣成默认的析构函数。

4. 对象⽣命周期结束时,系统会⾃动调⽤析构函数。

5. 跟构造函数类似,我们不写编译器⾃动⽣成的析构函数对内置类型成员不做处理,⾃定类型成员会 调⽤他的析构函数。

6. 还需要注意的是我们显⽰写析构函数,对于⾃定义类型成员也会调⽤他的析构,也就是说⾃定义类 型成员⽆论什么情况都会⾃动调⽤析构函数

7. 如果类中没有申请资源时,析构函数可以不写,直接使⽤编译器⽣成的默认析构函数,如Date;如 果默认⽣成的析构就可以⽤,也就不需要显⽰写析构,如MyQueue;但是有资源申请时,⼀定要 ⾃⼰写析构,否则会造成资源泄漏,如Stack。

8. ⼀个局部域的多个对象,C++规定后定义的先析构。

(2)代码示例

#define MAX_STACK_SIZE 1000 
#include <iostream>
using namespace std;
typedef int STDataType;

class Stack
{
public :
    Stack(int n = 4)
    {
        _a = (STDataType*)malloc(sizeof(STDataType) * n);
        if (nullptr == _a)
        {
            perror("申请失败");
            return;
        }
        _capacity = n;
        _top = 0;
    }
    ~Stack()
    {
        cout << "~Stack()" << endl;
        free(_a);
        _a = nullptr;
        _top = _capacity = 0;
    }

private:
    STDataType* _a;
    size_t _capacity;
    size_t _top;
};//注意分号

//两个Stack实现队列
class Date
{
public:
    //无参构造函数
    Date()
    {
        _year = 1;
        _month = 1;
        _day = 1;
    }
    //带参构造函数
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;

    }

    //全缺省构造函数
    Date(int year=1, int month=1, int day=1)
    {
        _year = year;
        _month = month;
        _day = day;

    }
    void printf()
    {
        cout << _year << "/" << _month << "/" << _day << endl;
    }
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    // 如果留下三个构造中的第⼆个带参构造,第⼀个和第三个注释掉

        // 编译报错:error C2512 : “Date”:没有合适的默认构造函数可⽤
    // 调⽤默认构造函数
    Date d1;
    Date d2(2025, 1, 1);
        // 调⽤带参的构造函数

        //注意:如果通过⽆参构造函数创建对象时,对象后⾯不⽤跟括号,否则编译器⽆法

        // 区分这⾥是函数声明还是实例化对象

        // warning C4930: “Date d3(void)”: 未调⽤原型函数(是否是有意⽤变量定义的? )
    Date d3();
    d1.printf();
    d2.printf();
    return 0;
}

二、析构函数

(1)概念:

1. 析构函数名是在类名前加上字符~。

2. ⽆参数⽆返回值。(这⾥跟构造类似,也不需要加void)

3. ⼀个类只能有⼀个析构函数。若未显式定义,系统会⾃动⽣成默认的析构函数。

4. 对象⽣命周期结束时,系统会⾃动调⽤析构函数。

5. 跟构造函数类似,我们不写编译器⾃动⽣成的析构函数对内置类型成员不做处理,⾃定类型成员会 调⽤他的析构函数。

6. 还需要注意的是我们显⽰写析构函数,对于⾃定义类型成员也会调⽤他的析构,也就是说⾃定义类 型成员⽆论什么情况都会⾃动调⽤析构函数。 

7. 如果类中没有申请资源时,析构函数可以不写,直接使⽤编译器⽣成的默认析构函数,如Date;如 果默认⽣成的析构就可以⽤,也就不需要显⽰写析构,如MyQueue;但是有资源申请时,⼀定要 ⾃⼰写析构,否则会造成资源泄漏,如Stack。

8. ⼀个局部域的多个对象,C++规定后定义的先析构。

(2)代码如下(示例):

#define MAX_STACK_SIZE 1000 
#include <iostream>
using namespace std;
typedef int STDataType;

class Stack
{
public :
    Stack(int n = 4)
    {
        _a = (STDataType*)malloc(sizeof(STDataType) * n);
        if (nullptr == _a)
        {
            perror("申请失败");
            return;
        }
        _capacity = n;
        _top = 0;
    }
    ~Stack()
    {
        cout << "~Stack()" << endl;
        free(_a);
        _a = nullptr;
        _top = _capacity = 0;
    }

private:
    STDataType* _a;
    size_t _capacity;
    size_t _top;
};//注意分号

//两个Stack实现队列
class MYQueue
{
public:
//编译器默认⽣成MyQueue的析构函数调⽤了Stack的析构,释放的Stack内部的资源
// 显⽰写析构,也会⾃动调⽤Stack的析构
/*~MyQueue()
{}*/
private:
    Stack pushst;
    Stack popst;
};
int main()
{
    Stack st;
    MYQueue mq;

    return 0;
}


总结

析构函数和构造函数我也觉得特别难懂~~>_<~~


http://www.niftyadmin.cn/n/5693187.html

相关文章

选择网络安全模式启动Windows系统,解决PC无法连接网络问题

目录 1、电脑无法连接网络 2、发现C:\Windows\System32\drivers路径下的很多文件不见了 3、使用360安全卫士中的断网急救箱工具修复&#xff0c;也就解决不了问题 4、重启系统&#xff0c;以网络安全模式启动系统&#xff0c;修复系统网络模块&#xff0c;完美解决问题 5、…

C++ 算法学习——1.6 前缀和与二维前缀和算法

前缀和算法&#xff08;Prefix Sum Algorithm&#xff09;&#xff1a; 概念&#xff1a;前缀和算法通过在遍历数组时计算前缀和&#xff08;从数组的第一个元素开始累加到当前元素的和&#xff09;&#xff0c;可以在O(1)时间内得到任意区间的子数组和&#xff0c;而不需要重复…

停车场停车位检测数据集2166张 违停 带标注 voc yolo 2类

停车场停车位检测数据集2166张 违停 带标注 voc yolo 2类 分类名: (图片张数&#xff0c;标注个数) occupied :(1035&#xff0c;2634) empty: (1131, 4280) 总数:(1230&#xff0c;691 4) 总类(nc): 2类 停车场停车位检测数据集介绍 数据集名称 停车场停车位检测数据集 (Pa…

BGP路由原理详解

&#x1f423;个人主页 可惜已不在 &#x1f424;这篇在这个专栏 华为_可惜已不在的博客-CSDN博客 &#x1f425;有用的话就留下一个三连吧&#x1f63c; 目录 一. BGP简介: 二. BGP报文中的角色 BGP的报文 BGP处理过程 BGP有限状态机 BGP属性 三. BGP作用 四. BGP选路 ​…

Golang | Leetcode Golang题解之第458题可怜的小猪

题目&#xff1a; 题解&#xff1a; func poorPigs(buckets, minutesToDie, minutesToTest int) int {if buckets 1 {return 0}combinations : make([][]int, buckets1)for i : range combinations {combinations[i] make([]int, buckets1)}combinations[0][0] 1iterations…

每日一题|871. 最低加油次数|动态规划、内层逆序遍历

题目分析&#xff1a;找到第一个能够实现当前油量能够行驶的最大距离大于等于目标距离&#xff0c;且加油次数最小的加油站和加油次数。 每次加油之后能够行驶的最大距离都是由上一次加油的距离决定的&#xff0c;因此使用dp。 1、dp数组定义 dp[i]是一个一维数组&#xff0…

鸿蒙next开发者第一课02.DevEcoStudio的使用-习题

【习题】DevEco Studio的使用 通过/及格分80/ 满分100 判断题 1. 如果代码中涉及到一些网络、数据库、传感器等功能的开发&#xff0c;均可使用预览器进行预览。F 正确(True)错误(False) 预览器不能进行传感器等特殊功能的开发,需要使用真机开发 2. module.json5文件中的…

class 031 位运算的骚操作

这篇文章是看了“左程云”老师在b站上的讲解之后写的, 自己感觉已经能理解了, 所以就将整个过程写下来了。 这个是“左程云”老师个人空间的b站的链接, 数据结构与算法讲的很好很好, 希望大家可以多多支持左程云老师, 真心推荐. 左程云的个人空间-左程云个人主页-哔哩哔哩视频…