初识C++(三)构造函数和析构函数

目录

一、构造函数:

1.构造函数的概念:

2.构造函数的特性:

3.构造函数的形式:

4.为什么要引出构造函数这一概念

5.默认构造函数包括:

6.对默认生成的构造函数不处理内置类型的成员这事的解决办法:

二、析构函数:

1.析构函数的概念: 

2.析构函数的特性:

三、构造和析构函数其余的特点:


一、构造函数:

1.构造函数的概念:

  • 构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员都有一个合适的初始值,并且在对象的生命周期内只调用一次。

2.构造函数的特性:

  • 函数名与类名相同。
  • 无返回值。
  • 编译器自动调用对应的构造函数。
  • 构造函数可以重载。
  • 需要注意的一点是,虽然构造函数叫"构造"函数,但是构造函数并不是用来构造对象的,构造函数的功能是用来完成对象的初始化

3.构造函数的形式:

	Date(int year, int month, int day)   //进行初始化的操作{_year = year;_month = month;_day = day;}

4.为什么要引出构造函数这一概念

看下面的代码,对于Date类,可以通过InitDate公有的方法给对象设置内容,但是如果每次创建对象都调用该方法设置信息,未免有点麻烦,那能否在对象创建时,就将信息设置进去呢?
现在我们的需求就是不通过对象去调用初始化对象的数据,我们希望当这个对象创建出来的时候,他就已经是具有一定的初始值的,那么如何做到我们现在的这个需求的呢?
由此,引入了构造函数这一个概念,如下所示:

(1) 下面这段代码需要自己初始化:

d1,d2,d3都需要初始化,太麻烦了

#include<iostream>
using namespace std;
class Date
{
public:void InitDate(int year, int month, int day)   //进行初始化的操作{_year = year;_month = month;_day = day;}void PrintDate()   //打印进行检测{cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d1, d2, d3;d1.InitDate(2020, 4, 30);//需要自己初始化d1.PrintDate();d2.InitDate(2020, 4, 29);d2.PrintDate();d3.InitDate(2020, 4, 28);d3.PrintDate();
}

(2)自动初始化(构造函数):

#include<iostream>
using namespace std;
class Date
{
public:Date(int year, int month, int day)   //进行初始化的操作{_year = year;_month = month;_day = day;}void PrintDate()   //打印进行检测{cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d1(2002,11,05);//在创建对象时就一起初始化,编译器会自动调用进行初始化	d1.PrintDate();
}

用了重构函数之后,创建对象的时候,编译器自动调用Date


 如果不想传参数,函数重载一个构造函数。Date() 和 Date(int year,int month,int day)

#include<iostream>
using namespace std;
class Date
{
public:Date()//不传参时调用这个构造函数{_year=1;_month=1;_day=1;}Date(int year, int month, int day)   //传参时调用这个函数{_year = year;_month = month;_day = day;}void PrintDate()   //打印进行检测{cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d1(2002,11,05);//在创建对象时就一起初始化,编译器会自动调用进行初始化	d1.PrintDate();Date d2;   //注意这里不能写成d2(),不能加括号d2.PrintDate();
}

 

d1调用了Date(int year,int month,int day)

d2调用了Date()


当然也可以使用缺省参数:

#include<iostream>
using namespace std;
class Date
{
public:Date(int year=1, int month=1, int day=1)   //进行初始化的操作{_year = year;_month = month;_day = day;}void PrintDate()   //打印进行检测{cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d1(2002,11,05);//在创建对象时就一起初始化,编译器会自动调用进行初始化	d1.PrintDate();Date d2(2013); //不能加括号d2.PrintDate();Date d3(2014,5); //不能加括号d2.PrintDate();Date d2; //不能加括号d2.PrintDate();
}

 缺省函数的优势。


如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成 

   默认生成的构造函数:
        内置类型的成员不做处理  ----  C++这里没有处理好,就会导致有数据的随机值
        自定义类型的成员做处理


 对内置类型的成员不做处理:

#include<iostream>
using namespace std;
class Date
{
public://使用默认的构造函数,但是因为是内置类型,它就不会初始化void PrintDate()   //打印进行检测{cout << _year << "/" << _month << "/" << _day << endl;}
private:int _year;int _month;int _day;
};int main()
{Date d1;//在创建对象时就一起初始化,编译器会自动调用进行初始化	d1.PrintDate();Date d2; //不能加括号d2.PrintDate();
}

 内置类型产生的是随机值


对自定义类型的成员处理:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Stack
{
public:Stack(){std::cout << "Stack类型的初始化" << std::endl;_a = nullptr;_size = _capacity = 0;}Stack(int capacity){_a = (int*)malloc(sizeof(int) * capacity);if (nullptr == _a){perror("malloc error");exit(-1);}_capacity = capacity;_size = 0;}int* _a;int _size;int _capacity;
};
class MyQueue{
public://默认生成构造函数,对自定义类型,会调用它的默认构造函数void push(int x){}
private:Stack _pushST;Stack _popST;
};
int main()
{MyQueue q;return 0;
}

 实现步骤如下表:

5.默认构造函数包括:

(1)编译器默认生成的构造函数 

(2)无参构造函数  

(3)全缺省构造函数


6.对默认生成的构造函数不处理内置类型的成员这事的解决办法:

C++在C11的时候打了补丁:

在声明那个地方加上一个缺省值,在无构造函数时,编译器自动生成的构造函数,会调用那里的值,就完成了没有自己写构造函数,也对内置类型的初始化。

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
{
public://默认生成的构造类型,对内置类型不处理
private://这不是初始化,而是对构造和析构函数对内置类型不处理这个问题的解决方法//声明位置给缺省值,如果你不想写构造函数,你这样子写,它会默认给你初始化成这些值int _year=1;int _month=1;int _day=1;
};

 

二、析构函数:

1.析构函数的概念: 

主要作用于在对象销毁前,执行一些清理工作(如释放new开辟在堆区的空间)

2.析构函数的特性:

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


//析构函数
~Date()//没有参数
{cout << "~Date()"<<endl;_year = 0;_month = 0;_day = 0;
}

 析构函数具体放置的位置:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Date
{
public://默认生成的构造类型,对内置类型不处理Date(int year=1, int month = 1, int day = 1){//cout << "Date()" << endl;_year = year;_month = month;_day = day;}void print(){cout << _year << "年" << _month << "月" << _day << "日" << endl;}~Date()//没有参数   析构函数{cout << "~Date()"<<endl;_year = 0;_month = 0;_day = 0;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2023,11,5);//构造函数Date d2;//构造函数中的缺省函数d1.print();d2.print();return 0;
}

 同样,编译器也有默认生成的析构函数,对自定义类型起作用,对内置类型不起作用。

三、构造和析构函数其余的特点:

  • 构造函数和析构函数是一种特殊的公有成员函数,每一个类都有一个默认的构造函数和析构函数;
  • 构造函数在类定义时由系统自动调用,析构函数在类被销毁时由系统自动调用;
  • 构造函数的名称和类名相同,一个类可以有多个构造函数,只能有一个析构函数。不同的构造函数之间通过参数个数和参数类型来区分
  • 我们可以在构造函数中给类分配资源,在类的析构函数中释放对应的资源。
  • 如果程序员没有提供构造和析构,系统会默认提供
  • 构造函数 和 析构函数,必须定义在public里面,才可以调用

    感谢各位大佬的观看,如果觉得还不错的话,支持一下我前面的文章,你的支持就是我创作的动力!

     初识C++(一)啥是C++,关键字,命名空间 ,输入输出,缺省函数:http://t.csdnimg.cn/tJM4K

     初识C++(二)引用,内联函数,auto:http://t.csdnimg.cn/ljtkY

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/770921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python机器学习系列】skearn机器学习模型的保存---pickle法

这是我的第246篇原创文章。 一、引言 pickle是Python 的标准库&#xff0c;用于序列化对象。可以使用 pickle.dump()将模型保存到文件&#xff0c;然后使用 pickle.load()从文件中加载模型。 序列化&#xff1a;指将一个对象转换为字节流&#xff0c;能够存储在文件或网络上&…

HTML快速入门笔记

一、HTML快速入门 说明&#xff1a;所有加*号内容代表不常用&#xff0c;了解即可。 HTML概述 超文本&#xff1a;Web是一个超文本的集合&#xff1b;超文本是web的基本组成单元&#xff0c;也成为网页或HTML文档&#xff0c;Web页等&#xff0c;通常以.html或.htm为后缀的文件…

Apache SeaTunnel 初识

文章目录 Apache SeaTunnel 初识为什么我们需要SeaTunnel使用场景特点解决的问题工作流连接器输入插件过滤插件输出插件引擎spark 和 flink 引擎SeaTunnel 引擎集群管理核心功能Apach

力扣1----10(更新)

1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按…

计算机网络:现代通信的基石

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

「Linux系列」Linux网络通讯/系统管理/系统设置/备份压缩/设备管理命令

文章目录 一、Linux网络通讯命令二、Linux系统管理命令三、Linux系统设置命令四、Linux备份压缩命令五、Linux设备管理命令六、相关链接 一、Linux网络通讯命令 Linux网络通讯命令是Linux系统中用于管理和调试网络功能的一系列工具。这些命令可以帮助用户查看网络状态、测试网…

SNMP学习笔记SNMPWALK命令

SNMPWALK是SNMP的一个工具&#xff0c;它使用SNMP的GETNEXT请求查询指定OID入口的所有OID树信息&#xff0c;并显示给用户。 IT监控系统常用snmpwalk获取支持SNMP的网络设备信息&#xff0c;使用snmpwalk收集交换机、路由器的CPU、内存、端口流量等信息。 使用snmpwalk需要安装…

Matlab实现序贯变分模态分解(SVMD)

大家好&#xff0c;我是带我去滑雪&#xff01; 序贯变分模态分解(SVMD) 是一种信号处理和数据分析方法。它可以将复杂信号分解为一系列模态函数&#xff0c;每个模态函数代表信号中的特定频率分量。 SVMD 的主要目标是提取信号中的不同频率分量并将其重构为原始信号。SVMD的基…

异地两台电脑如何共享文件?

在当前数字化时代&#xff0c;人们对于数据的使用和管理变得越来越便捷。由于工作和生活的需要&#xff0c;我们常常需要在异地的电脑间共享文件。这给我们的工作和生活带来了一定程度的不便。有没有一种便捷的方法可以让异地的电脑实现文件的共享呢&#xff1f;答案是肯定的。…

flutter 父组件调用子组件方法

标题在Flutter中&#xff0c;父组件可以通过GlobalKey来引用子组件&#xff0c;并调用子组件的方法。以下是一个简单的例子&#xff1a; 在这个例子中&#xff0c;ParentComponent 有一个GlobalKey&#xff0c;它被传递给了ChildComponent。当按钮被点击时&#xff0c;通过chi…

06 mybatis </sql>

文章目录 products.sqlpom.xmlmybatis-config.xmlProductsMapper.xmlProductsMapperImpl.javaProducts.javaDButil.javaProductsMapperImplTest.javaMapperTest.java products.sql create table products (product_id int auto_increment comment 产品IDprimary key,prod…

知识图谱-图数据库-neo4j (1)踩坑记录

1、neo4j 安装 材料 &#xff1a; openjdk11 (neo4j 最低jdk版本要求) neo4j-community-4.4.30 CentOS 7.8 Release Date: 25 January 2024 Neo4j 4.4.30 is a maintenance release with many important improvements and fixes. Neo4j Deployment Center - Graph Database…

vuex状态管理的使用

一、创建store,单个store的使用 1、 /*** 该文件用于创建vuex中最核心的store*///引入Vuex import Vuex from vuex; import Vue from "vue";//使用vuex来集中管理状态,必要 //new store的前提是必须要使用Vuex插件 Vue.use(Vuex);//创建actions(本质就是对象) 用于…

【前端面试3+1】01闭包、跨域

一、对闭包的理解 定义&#xff1a; 闭包是指在一个函数内部定义的函数&#xff0c;并且该内部函数可以访问外部函数的变量。闭包使得函数内部的变量在函数执行完后仍然可以被访问和操作。 特点&#xff1a; 闭包可以访问外部函数的变量&#xff0c;即使外部函数已经执行完毕。…

vue项目中使用vue-pdf或pdf.Js,实现在页面上预览pdf内容

一。vue-pdf 1. 安装vue-pdf npm install --save vue-pdf2.页面引入 js部分 import pdf from "vue-pdf";data(){return {pdfUrl: "",pageTotal: 0,} }mounted(){this.pdfUrl pdf.createLoadingTask(pdf文件路径url);// 获取页码this.pdfUrl.promise…

Linux 搭建jenkins docker

jekin docker gitee docker 安装 jenkins docker run -d --restartalways \ --name jenkins -uroot -p 10340:8080 \ -p 10341:50000 \ -v /home/docker/jenkins:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker je…

QT数据类型和容器用法

Qt库提供了基于通用模板的容器类, 这些类可用于存储指定类型的数据项&#xff0c;Qt中这些容器类的设计比STL容器更轻&#xff0c;更安全且更易于使用。容器类也都是隐式共的&#xff0c;它们是可重入的&#xff0c;并且已针对速度/低内存消耗和最小的内联代码扩展进行了优化&a…

【解析几何】 【多源路径】 【贪心】1520 最多的不重叠子字符串

作者推荐 视频算法专题 本身涉及知识点 解析几何 图论 多源路径 贪心 LeetCode1520. 最多的不重叠子字符串 给你一个只包含小写字母的字符串 s &#xff0c;你需要找到 s 中最多数目的非空子字符串&#xff0c;满足如下条件&#xff1a; 这些字符串之间互不重叠&#xff0…

简单讲讲spring事务的传播机制

事务传播机制就像是一个指挥家&#xff0c;控制着程序中的各种操作&#xff08;比如修改数据库&#xff09;何时开始、何时结束&#xff0c;以及如何处理错误。 保证数据一致性&#xff1a;想象一下你在网上购物&#xff0c;你需要先从银行账户扣款&#xff0c;然后再把商品加入…

Wireshark使用实训---分析IP包

1.Wireshark简介和作用 Wireshark是一个开源的网络分析工具&#xff0c;用于捕捉和分析网络数据包。它可以帮助网络管理员和安全专家监控和解决网络问题&#xff0c;同时也可以用于学习和教学网络通信原理。 Wireshark可以在网络中捕获和分析传输的数据包&#xff0c;包括协议…