• C++学习笔记12 - 构造函数和析构函数


    一、典型的C++面向对象编程

    1、元素

    • 头文件hpp中类的定义
    • 源文件cpp中类的实现(构造函数、析构函数、方法)
    • 主程序

    2、实战中,一般一个cpp和一个hpp文件配对,描述一个class,class的名字和文件名相同。

    3、面向对象式编程总结

    • 整个工作分为2大块:一个是建模和编写类库,一个是使用类库来编写主程序完成任务。
    • 有些人只负责建模和编写类库,譬如开发OpenCV的人。
    • 有些人直接调用现成类库来编写自己的主任务程序,譬如使用OpenCV分析一张图片中有没有电动车。
    • 难度上不确定,2个都有可能很难或很简单。

    4、C++学习的三重境界

    • 学习C++第一重境界就是语法层面,先学会如何利用C++来建模、来编程,学习语法时先解决难度大问题。
    • 学习C++第二重境界就是解决问题层面,学习如何理解并调用现成类库来编写主程序解决问题。
    • 学习C++的第三重境界是编写类库和sample给别人用,需要基础好且有一定架构思维。

    二、C++的构造函数 和 析构函数

    1、什么是构造函数

    • constructor,字面意思是用来构造对象的函数;destructor,字面意思是用来析构对象的函数。
    • 可以理解为语言自带的一种hook函数(回调函数,满足一定条件下会被自动调用的函数)
    • 当对象产生时constructor会被自动调用,一般用于初始化class的属性、分配class内部需要的动态内存。
    • 当对象消亡时destructor会被自动调用,一般用于回收constructor中分配的动态内存,避免内存丢失。

    2、构造和析构一般用法

    • 不写时C++会自动提供默认的构造和析构,也可以显式提供默认构造和析构函数。
    • 构造和析构函数不需要返回值类型,构造函数可以带参或不带参,析构函数不带参。
    • 构造函数可以重载(overlord),析构函数不需要重载。

    3、为什么需要构造函数和析构函数

    • 构造函数可以看作是对象的初始化式,注意对比对象和变量的初始化区别。
    • 构造函数可以为对象完成动态内存申请,同时在析构函数中再释放,形成动态内存的完整使用循环。
    • C语言中struct无构造函数概念,所以struct中需要用到动态内存时必须在定义struct变量后再次单独申请和释放,而这些操作都需要程序员手工完成。
    • C++ class的构造和析构特性,是C++支持面向对象编程的一大语言特性。

    三、在构造和析构函数中使用动态内存

    1、析构函数的使用

    • 析构函数在对象销毁时自动调用,一般有以下2种情况
    • 用new分配的对象,分配在堆上,用delete显示析构
    • 分配在栈上的对象,当栈释放时自动析构
    • 普通情况下析构函数都是空的,因为不必做什么特别的事情

    2、在class中使用动态内存变量

    • 什么情况下用动态内存?需要大块内存,且需要按需灵活的申请和释放,用栈怕爆、用全局怕浪费和死板。
    • 在class 中增加一个int* 指针,用于指向一个int类型元素的内存空间。
    • 在构造函数中分配动态内存
    • 在析构函数中回收动态内存
    • 将动态内存从int变量升级到int数组变量
    • 实战中C++常用的动态内存往往是容器vector那些,后面会讲到。

    3、用valgrind工具查看内存泄漏

    • valgrind工具介绍,参考:https://blog.csdn.net/u012662731/article/details/78652651
    • 安装:sudo apt-get install valgrind(ubuntu16.04 X64)
    • 编译使用:主要是添加-g参数便于调试时有行号 g++ person.cpp main.cpp -g -o apptest
    • 使用:valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./apptest

    四、构造函数与类的成员初始化

    1、构造函数一大功能就是初始化成员变量

    • 默认构造函数不带参,无初始化功能。
    • 若无其他构造函数,则默认构造函数可以省略。但若有哪怕1个其他的构造函数,则默认构造函数不能省略,必须写上。
    • 栈上分配对象时,若使用默认构造函数,则对象变量后面不加空的(),若用带参构造才需要加(初始化参数)。

    2、C++的成员初始化列表

    • 一般用于带参构造函数中,用来给属性传参赋值。
    • 成员初始化列表和构造函数之间用冒号间隔,多个列表项之间用逗号间隔。
    • 初始化列表可以替代构造函数内的赋值语句,达到同样的效果。

    3、构造函数使用参数默认值

    • class声明时可以给函数形参赋值一个默认值,实际调用时若不传参就使用默认值。
    • 方法实现时形参可以不写默认值,但是实际是按照声明时的默认值规则的。
    • 有默认值情况,要注意实际调用不能有重载歧义,否则编译不能通过。
    • 所有参数都带默认值的构造函数,1个可以顶多个构造函数。
  • 相关阅读:
    软件测试要学会哪些东西才能拿2w+的工资?
    使用Python的turtle模块绘制花形图案(含详细Python代码与注释)
    使用react-sizeme解决react-grid-layout中侧栏(抽屉)展开或隐藏时不会自适应容器大小的问题
    Docker容器内使用matplotlib.pyplot
    简单好用的 SemVer: 如何命名你的应用版本
    Go-Zero从0到1实现微服务项目开发(二)
    Mybatis 查询数据库
    【英语:基础高阶_全场景覆盖表达】K10.口语主题陈述——地点类
    【计算机网络微课堂】5.6 TCP超时重传时间的选择
    小知识(6) el-table表格选中行和回显行(vue3)
  • 原文地址:https://blog.csdn.net/qq_38958704/article/details/126253798